The Execution Engine: Sliding Windows and Triple-Nested Loops in Mercury Division

In our last post, “The Division Stage-Setter,” we explored how Mercury outsmarts the CPU division limit. Instead of blindly guessing and subtracting to find a quotient, mercuryAbsDiv builds a multi-dimensional Table[8][16] array in its scratch memory—effectively memorizing its own times tables for the divisor across every possible 4-bit nibble shift.

But a pre-computed table is only useful if you have an engine built to navigate it. Today, we are looking at the execution phase: a triple-nested loop that dynamically slides our pre-computed grid across the dividend, turning a massive arbitrary-precision division problem into a lightning-fast sequence of pure lookups and subtractions.

To understand how the engine works without getting lost in the syntax, we are going to build it piece by piece.

Phase 1: Navigating the Places (The Outer Loop)

Division requires us to start at the most significant parts of our number and work our way down. The outermost loop of our execution engine handles this macro-level movement.

It starts at the highest 32-bit place of the dividend and slowly steps down to the identity place (the ones place).

// Step down through the 32-bit places of the dividend
for (int i = Precision - 1; i >= 0; i--) {
    
    // ... nibble and subtraction logic goes here ...
    
    dividend[1]++; // Shift the dividend window for the next place
}

The crucial piece of logic here is dividend[1]++. In Mercury’s architecture, index [1] holds the exponent. By incrementing it at the end of every loop, we physically shift our working frame of reference down the array. We are systematically sliding the divisor’s window across the dividend.

Phase 2: Slicing into Nibbles (The Middle Loop)

Once our window is locked onto a specific 32-bit place, we need to zoom in.

As we established in the previous post, our pre-computed table is based on 4-bit nibbles. Since there are exactly 8 nibbles in a 32-bit word, our middle loop slices the current place into 8 discrete steps, starting from the highest nibble ($7$) down to the lowest ($0$).

for (int i = Precision - 1; i >= 0; i--) {
    
    // Step down through the 8 nibbles of the current place
    for (int p = 7; p >= 0; p--) {
        
        // ... lookup and strike logic goes here ...
        
    }

    dividend[1]++;
}

The variable p here maps exactly to the q dimension of our Table[8][16]. It tells the engine exactly which layer of our shifted, pre-multiplied grid we need to look at for this specific spatial position.

Phase 3: The Lookup and Strike (The Inner Loop)

Now we drop the hammer. Inside the innermost loop, the engine tests the pre-computed multiples of our divisor, checking the largest possible value ($15$, or 0xF in hex) down to $0$.

for (int i = Precision - 1; i >= 0; i--) {
    for (int p = 7; p >= 0; p--) {
        
        // Test the pre-computed multiples from 15 down to 0
        for (int d = 0xF; d >= 0; d--) {
            uint *x = Table[p][d]; // Grab the pre-computed chunk

            // Does it fit?
            if (mercuryAbsCmp(Precision, dividend, x) >= 0) {
                
                // Strike: Subtract it from the dividend
                mercurySub(stack, Precision, dividend, x, dividend);

                // Log the quotient piece in its exact spatial position
                reg[i] += ((uint) d) << (p * 4);

                // ... exit logic ...
                d = -1; // Break the inner loop, move to the next nibble
            }
        }
    }
    dividend[1]++;
}

This is the ultimate payoff of our preparation. There is no guesswork. The engine simply checks if the pre-computed chunk fits (mercuryAbsCmp). If it does, it executes a single subtraction (mercurySub) and instantly logs the quotient piece directly into the result array (reg[i] += ((uint) d) << (p * 4)), perfectly aligning it using the exact same bit-shift math we used to generate the table.

Once a fit is found and subtracted, it forces d = -1 to break the inner loop and instantly move on to the next nibble.

The Clean Exit: A Surgical Optimization

If you look closely at the full mercuryAbsDiv source code, there is one final optimization nestled inside that innermost strike loop.

Every time Mercury performs a successful subtraction, it checks if the dividend has reached absolute zero. If it has, there is no reason to continue shifting the window or testing lower places. The math is completely finished. To immediately halt the engine, Mercury uses a direct goto ret; jump.

                    if (mercuryIsZero(Precision, dividend)) {
                        goto ret; // Break out of all three loops instantly
                    }

While the goto statement is often treated as taboo in modern, high-level application development, in bare-metal C engine architecture, it is a surgical tool. It allows the processor to instantly break out of a triple-nested loop the exact millisecond the work is done, without having to cascade through multiple break conditions or evaluate a chain of boolean flags. It saves precious clock cycles and guarantees a perfectly clean exit.

Up Next: Entering the Power Tier

With addition, subtraction, multiplication, and division firmly established, we have conquered the linear and geometric foundations of the Mercury engine.

Next time, we step into the highest foundational level of mathematics: The Power Tier. We will explore how exponential growth forces our inverse operations to split into roots and logarithms, and how Mercury relies on those exact structural relationships to dynamically converge on the hardest calculations in silicon.

JWCEssentials on GitHub

JWCEssentials/C/Mercury/Mercury.c

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>


The reCAPTCHA verification period has expired. Please reload the page.

This site uses Akismet to reduce spam. Learn how your comment data is processed.