Hi,<br><br>I'm translating porting a Delphi component that uses x86-64 assembly.<br><br>So far, most of the asm code compiles and works fine.<br><br>The only thing that i could not translate is the .SAVENV directive. See <a href="http://blogs.embarcadero.com/abauer/2011/10/10/38940">http://blogs.embarcadero.com/abauer/2011/10/10/38940</a> and <a href="http://docwiki.embarcadero.com/RADStudio/en/Assembly_Procedures_and_Functions">http://docwiki.embarcadero.com/RADStudio/en/Assembly_Procedures_and_Functions</a><br>
<br>Seems that is necessary to save and restore the register with a specific alignment.<br><br>I would appreciate any help<br><br>The procedure is below.<br><br>The component is VirtualTreeView and full source can be found at <a href="http://virtual-treeview.googlecode.com/svn/trunk/Source/VirtualTrees.pas">http://virtual-treeview.googlecode.com/svn/trunk/Source/VirtualTrees.pas</a><br>
<br>procedure AlphaBlendLineMaster(Source, Destination: Pointer; Count: Integer; ConstantAlpha, Bias: Integer);<br><br>// Blends a line of Count pixels from Source to Destination using the source pixel and a constant alpha value.<br>
// The layout of a pixel must be BGRA.<br>// ConstantAlpha must be in the range 0..255.<br>// Bias is an additional value which gets added to every component and must be in the range -128..127<br><br>asm<br><br>{$ifdef CPU64}<br>
// RCX contains Source<br>// RDX contains Destination<br>// R8D contains Count<br>// R9D contains ConstantAlpha<br>// Bias is on the stack<br><br>        .SAVENV XMM6  //todo see how implement in fpc<br><br>        // Load XMM3 with the constant alpha value (replicate it for every component).<br>
        // Expand it to word size.<br>        MOVD        XMM3, R9D    // ConstantAlpha<br>        PUNPCKLWD   XMM3, XMM3<br>        PUNPCKLDQ   XMM3, XMM3<br><br>        // Load XMM5 with the bias value.<br>        MOV         R10D, [Bias]<br>
        MOVD        XMM5, R10D<br>        PUNPCKLWD   XMM5, XMM5<br>        PUNPCKLDQ   XMM5, XMM5<br><br>        // Load XMM4 with 128 to allow for saturated biasing.<br>        MOV         R10D, 128<br>        MOVD        XMM4, R10D<br>
        PUNPCKLWD   XMM4, XMM4<br>        PUNPCKLDQ   XMM4, XMM4<br><br>@1:     // The pixel loop calculates an entire pixel in one run.<br>        // Note: The pixel byte values are expanded into the higher bytes of a word due<br>
        //       to the way unpacking works. We compensate for this with an extra shift.<br>        MOVD        XMM1, DWORD PTR [RCX]   // data is unaligned<br>        MOVD        XMM2, DWORD PTR [RDX]   // data is unaligned<br>
        PXOR        XMM0, XMM0    // clear source pixel register for unpacking<br>        PUNPCKLBW   XMM0, XMM1{[RCX]}     // unpack source pixel byte values into words<br>        PSRLW       XMM0, 8       // move higher bytes to lower bytes<br>
        PXOR        XMM1, XMM1    // clear target pixel register for unpacking<br>        PUNPCKLBW   XMM1, XMM2{[RCX]}     // unpack target pixel byte values into words<br>        MOVQ        XMM2, XMM1    // make a copy of the shifted values, we need them again<br>
        PSRLW       XMM1, 8       // move higher bytes to lower bytes<br><br>        // Load XMM6 with the source alpha value (replicate it for every component).<br>        // Expand it to word size.<br>        MOVQ        XMM6, XMM0<br>
        PUNPCKHWD   XMM6, XMM6<br>        PUNPCKHDQ   XMM6, XMM6<br>        PMULLW      XMM6, XMM3    // source alpha * master alpha<br>        PSRLW       XMM6, 8       // divide by 256<br><br>        // calculation is: target = (alpha * master alpha * (source - target) + 256 * target) / 256<br>
        PSUBW       XMM0, XMM1    // source - target<br>        PMULLW      XMM0, XMM6    // alpha * (source - target)<br>        PADDW       XMM0, XMM2    // add target (in shifted form)<br>        PSRLW       XMM0, 8       // divide by 256<br>
<br>        // Bias is accounted for by conversion of range 0..255 to -128..127,<br>        // doing a saturated add and convert back to 0..255.<br>        PSUBW       XMM0, XMM4<br>        PADDSW      XMM0, XMM5<br>        PADDW       XMM0, XMM4<br>
        PACKUSWB    XMM0, XMM0    // convert words to bytes with saturation<br>        MOVD        DWORD PTR [RDX], XMM0   // store the result<br>@3:<br>        ADD         RCX, 4<br>        ADD         RDX, 4<br>        DEC         R8D<br>
        JNZ         @1<br>{$endif}<br>end; <br>