Hi,<br><br>I'm porting some Delphi assembly code.<br><br>It worked fine with fpc 2.6.0 i386-64bit windows compiler<br><br>When i tried the same code with fpc 2.6.0 i386-64bit for linux it failed to compile with the following error:<br>
<br>Error: Asm: 16 or 32 Bit references not supported<br><br>at the line<br> // Load XMM5 with the bias value.<br> MOVD XMM5, [Bias] //Bias = Integer<br><br>Is it a know issue or a limitation of linux version?<br>
<br>There's a workaround to this issue?<br><br>The complete procedure:<br><br>{$ASMMODE INTEL}<br><br>procedure AlphaBlendLineConstant(Source, Destination: Pointer; Count: Integer; ConstantAlpha, Bias: Integer);<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> //.NOFRAME<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> MOVD XMM5, [Bias]<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{[RDX]} // 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> // calculation is: target = (alpha * (source - target) + 256 * target) / 256<br>
PSUBW XMM0, XMM1 // source - target<br> PMULLW XMM0, XMM3 // 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><br>{$endif}<br><br>end;<br><br><br>