Results 1 to 2 of 2
Hi,
It's good that GCC support intel inline disassembly syntax, but it cannot even simply address local variables/parameters properly, making itself stupid and essentially useless, look at the following:
int ...
- 07-03-2010 #1Just Joined!
- Join Date
- Jul 2010
- Posts
- 4
Stupid GCC inline assembler doesn't even support local variable
Hi,
It's good that GCC support intel inline disassembly syntax, but it cannot even simply address local variables/parameters properly, making itself stupid and essentially useless, look at the following:
int myfunc(float f){
int x;
float fa[8];
asm(".intel_syntax noprefix\n"
"mov eax, [x]\n" // compile fail 1
"movss xmm1,[f]\n" // compile fail 2
"fld dword ptr [fa+4]\n" // compile fail 3
".att_syntax\n"
);
}
For compile fail 1, I can resolve using the following stupidly looking AT&T syntax (why stupid: empty instruction field, only preload register value), but it works nonetheless:
""::"a"(x)
though that cannot deal with "mov eax,[x+4]"
For compile fail 2 and 3, I've no idea except resolving to using other registers but apparantly I'm running out of registers in the real application, because I want to translate following working Visual C++ code into g++, but it seems not going to work unless I switch all to global variables which will incur massive cache misses,
// Compute posterior for all mixtures
void ComputeGMM( int n_mix, int n_dim, float *pObs,
float *pMean, float *pDCov,
float *pGConst,float *pOut ){
DWORD exp_bias = 127;
float exp_mul = (float)(-0.5*M_LOG2E);
float exp_max = 127.999f;
float exp_min = -126.999f;
float vout[4];
/* SSE optimized batch computation
ESI: c_mix
EDI: n_dim/4
*/
__asm{
// Load exponent multiplier -> xmm7
movss xmm7, exp_mul
unpcklps xmm7, xmm7
movlhps xmm7, xmm7
// Load max exponent -> xmm6
movss xmm6, exp_max
unpcklps xmm6, xmm6
movlhps xmm6, xmm6
// Load min exponent -> xmm5
movss xmm5, exp_min
unpcklps xmm5, xmm5
movlhps xmm5, xmm5
// Load the four exponent bias (DWORD 127) -> xmm4
movd xmm4, exp_bias
unpcklps xmm4, xmm4
movlhps xmm4, xmm4
// Load the four 1 s -> xmm3
movaps xmm3, xmm4
pslld xmm3, 23
// Load loop constants
mov esi, n_mix
mov edi, n_dim
shr esi, 2
mov ebx, pMean
mov edx, pDCov
re2:
mov ecx, edi
mov eax, pObs
xorps xmm2, xmm2
re1:
movaps xmm0, [eax]
subps xmm0, [ebx]
add eax, 16
mulps xmm0, xmm0
add ebx, 16
mulps xmm0, [edx]
add edx, 16
addps xmm2, xmm0
loop re1
// up to here, dot product results are in xmm2
// multiply by -0.5*M_LOG2E to convert from e^(-0.5x) to 2^x
mulps xmm2, xmm7
// cast full exponent into range
maxps xmm2, xmm5
minps xmm2, xmm6
// extract integer part -> xmm0
cvtps2dq xmm0, xmm2
// compute fractional part -> xmm2
cvtdq2ps xmm1, xmm0
subps xmm2, xmm1
// store fractional part -> vout[4]
movups vout, xmm2
// compute e^(fractional part) -> vout[4]
fld dword ptr [vout]
fld dword ptr [vout+4]
fld dword ptr [vout+8]
fld dword ptr [vout+12]
f2xm1
fstp dword ptr [vout+12]
f2xm1
fstp dword ptr [vout+8]
f2xm1
fstp dword ptr [vout+4]
f2xm1
fstp dword ptr [vout]
// integer exponent add bias 127
paddd xmm0, xmm4
// shift to floating point exponent position
pslld xmm0, 23
// combine(MUL) the 2 exp result -> xmm0, also multiply with GCONST
mov ecx, pGConst
movups xmm2, vout
mov eax, pOut
movaps xmm1, [ecx]
addps xmm2, xmm3
add ecx, 16
mulps xmm0, xmm2
mov pGConst,ecx
mulps xmm0, xmm1
movaps [eax], xmm0
add eax, 16
mov pOut, eax
dec esi
jnz re2
}
}
If you have any idea on how to do this, I would appreciate greatly! Also, I hope future versions of GCC can support intel syntax inline assembly better. Thanks!
Best regards,
Wang Xuancong
- 07-03-2010 #2
GCC's inline assembly does not allow you to directly insert your variable names. Instead, you need to do this using operands. Also, I don't know if you're allowed to use Intel syntax at all: I believe it needs to be AT&T syntax.
I don't do much assembly and I don't understand the second two lines, but this may be more of what you're looking for. In particular, note the way that I specify variables.Code:asm("movl %0, %%eax\n" "movss %1, %%xmm1\n" "fld dword ptr (%2+4)", :"r"(x), "f"(f), "r"(fa) : :"eax", "xmm1");
I have used this guide very successfully in the past, and it explains how to specify variables (among many other things):
GCC-Inline-Assembly-HOWTODISTRO=Arch
Registered Linux User #388732


Reply With Quote