<HTML>
<style> BODY { font-family:Arial, Helvetica, sans-serif;font-size:12px; }</style>I suppose what I'm trying to say is that I don't trust the compiler to actually use a register in the intermediate stages, especially in larger procedures.  To use AES-NI as an example, will it write back the partially-encrypted block to the stack after every round, or only after all the rounds have been completed? It would be perfectly logical to use the same variable to store the intermediate stage and the final stage if using a chain of intrinsics.  e.g:<br>
<br>
ciphertext := _mm_pxor(plaintext, roundkey[0]);<br>
<br>
for x := 1 to 9 do<br>
  ciphertext := _mm_aesenc(ciphertext, roundkey[x]);<br>
<br>
ciphertext := _mm_aesenclast(ciphertext, roundkey[10]);<br>
<br>
Of course, it's probably better to manually expand the for-loop here no matter if intrinsics or inline assembly is used, but I wouldn't want ciphertext to be written to the stack or some other backing store until at least the last round.  Unless another variable is used, I can see the compiler writing ciphertext to the stack after every intermedate step.  Granted a lot of it is down to the programmer. e.g:<br>
<br>
intermediate := _mm_pxor(plaintext, roundkey[0]);<br>
intermediate := _mm_aesenc(intermediate, roundkey[1]);<br>
intermediate := _mm_aesenc(intermediate, roundkey[2]);<br>
intermediate := _mm_aesenc(intermediate, roundkey[3]);<br>
intermediate := _mm_aesenc(intermediate, roundkey[4]);<br>
intermediate := _mm_aesenc(intermediate, roundkey[5]);<br>
intermediate := _mm_aesenc(intermediate, roundkey[6]);<br>
intermediate := _mm_aesenc(intermediate, roundkey[7]);<br>
intermediate := _mm_aesenc(intermediate, roundkey[8]);<br>
intermediate := _mm_aesenc(intermediate, roundkey[9]);<br>
ciphertext := _mm_aesenclast(intermediate, roundkey[10]);<br>
<br>
Or a messier one but which is more likely to guarantee that the intermediate stages remain in registers:<br>
<br>
ciphertext := _mm_aesenclast(<br>
  _mm_aesenc(<br>
    _mm_aesenc(<br>
      _mm_aesenc(<br>
        _mm_aesenc(<br>
          _mm_aesenc(<br>
            _mm_aesenc(<br>
              _mm_aesenc(<br>
                _mm_aesenc(<br>
                  _mm_aesenc(<br>
                    _mm_pxor(plaintext, roundkey[0]),<br>
                  roundkey[1]),<br>
                roundkey[2]),<br>
              roundkey[3]),<br>
            roundkey[4]),<br>
          roundkey[5]),<br>
        roundkey[6]),<br>
      roundkey[7]),<br>
    roundkey[8]),<br>
  roundkey[9]),<br>
roundkey[10]);<br>
<br>
This is where I feel that inline assembler is a little cleaner and guarantees a degree of certainty with efficiency.<br>
<br>
Gareth aka. Kit<br>
<br>
<br>
 <br>
<br>
<span style="font-weight: bold;">On Mon 18/03/19 07:00 , "Sven Barth" pascaldragon@googlemail.com sent:<br>
</span><blockquote style="BORDER-LEFT: #F5F5F5 2px solid; MARGIN-LEFT: 5px; MARGIN-RIGHT:0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px"><div dir="auto"><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">J. Gareth Moreton <<a href="javascript:top.opencompose('gareth@moreton-family.com','','','')">gareth@moreton-family.com</a>> schrieb am So., 17. März 2019, 23:27:<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> 
<div>I think one of the main issues with intrinsics is that you don't have much control over where results are stored.  Unless you're chaining a load of intrinsics together in a mess of function calls in actual parameters, the result is going to have to be stored in a local variable, which even on good days will end up being stored on the stack, and problems can occur if the stack isn't aligned and you're using SSE or AVX instructions.  After that, when you call the next intrinsic that uses the result, it will have to recall that data from memory. <br>

</div></blockquote></div></div><div dir="auto"><br>
</div><div dir="auto">And I believe that this is the advantage of intrinsics, because here the compiler *can* decide to use a different register. Especially if the compiler supports instruction scheduling and such. </div><div dir="auto">At work I've worked with AES-NI and I definitively preferred to work with the intrinsics and didn't have to care about what registers to use, because the compiler and optimizer took care of that. </div>
<div dir="auto">That is something that Pascal should stand for: ease of use. Assembler is not easy to use. </div><div dir="auto"><br>
</div><div dir="auto">Regards, </div><div dir="auto">Sven </div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div></div> 
</blockquote></div></div></div> 
 

</blockquote></HTML>