Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I implement an efficient 32 bit DivMod in 64 bit code
    primarykey
    data
    text
    <p>I want to use a <code>DivMod</code> function that operates exclusively on 32 bit operands. The <a href="http://docwiki.embarcadero.com/Libraries/en/System.Math.DivMod" rel="nofollow noreferrer">implementation in the RTL</a> returns values in 16 bit variables. Its declaration is:</p> <pre><code>procedure DivMod(Dividend: Cardinal; Divisor: Word; var Result, Remainder: Word); </code></pre> <p>So, I cannot use that since my inputs may overflow the return values.</p> <p>The naive Pascal implementation looks like this:</p> <pre><code>procedure DivMod(Dividend, Divisor: Cardinal; out Quotient, Remainder: Cardinal); begin Quotient := Dividend div Divisor; Remainder := Dividend mod Divisor; end; </code></pre> <p>This works splendidly but performs the division twice. Since the function is called by part of my code that is in a performance bottleneck, I would like to perform the division once only. To that end I am using Serg's 32 bit DivMod from this question: <a href="https://stackoverflow.com/questions/2397656/is-there-a-divmod-that-is-not-limited-to-words-65535">Is there a DivMod that is *not* Limited to Words (&lt;=65535)?</a></p> <pre><code>procedure DivMod(Dividend, Divisor: Cardinal; out Quotient, Remainder: Cardinal); asm PUSH EBX MOV EBX,EDX XOR EDX,EDX DIV EBX MOV [ECX],EAX MOV EBX,Remainder MOV [EBX],EDX POP EBX end; </code></pre> <p>This works perfectly.</p> <p>But now I would like a version of the function for 64 bit code. Note that I still want to operate on 32 bit operands, and return 32 bit values. </p> <p>Should I re-write the function using 64 bit assembler, or is it sufficient to use the <code>DivMod</code> overload from the RTL that operates on, and returns, 64 bit values? </p> <p>Specifically I would like to know if there is a performance benefit in writing 64 bit code that does 32 bit operations. Is that even possible? Or would I simply end up re-implementing the <code>DivMod</code> overload with <code>UInt64</code> parameters? If it is worth implementing a bespoke 64 bit asm version, how would I go about doing it, noting that the operands and operations are 32 bit.</p> <p>I think that it would look like this, but I am no expert and likely have got something wrong:</p> <pre><code>procedure DivMod(Dividend, Divisor: Cardinal; out Quotient, Remainder: Cardinal); asm MOV EAX,ECX // move Dividend to EAX MOV ECX,EDX // move Divisor to ECX XOR EDX,EDX // zeroise EDX DIV ECX // divide EDX:EAX by ECX MOV [R8],EAX // save quotient MOV [R9],EDX // save remainder end; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload