digitalmars.D.bugs - Inline assembly movd reg32/mem, xmmreg instruction produces incorrect machine code
- pmoore (115/115) Mar 14 2006 In the DMD code generator I believe the modrm reg and rm bits are being
- Thomas Kuehne (74/187) Mar 14 2006 -----BEGIN PGP SIGNED MESSAGE-----
In the DMD code generator I believe the modrm reg and rm bits are being
interpreted the wrong way round for this instruction.
Consider this assembly code:
asm
{
movd ECX, XMM0;
movd ECX, XMM1;
movd ECX, XMM2;
movd ECX, XMM3;
movd ECX, XMM4;
movd ECX, XMM5;
movd ECX, XMM6;
movd ECX, XMM7;
}
In visual C++ 2005 express (and my own calculations) produces the following
machine code:
66 0f 7e c1 ;movd ecx, xmm0
66 0f 7e c9 ;movd ecx, xmm1
66 0f 7e d1 ;movd ecx, xmm2
66 0f 7e d9 ;movd ecx, xmm3
66 0f 7e e1 ;movd ecx, xmm4
66 0f 7e e9 ;movd ecx, xmm5
66 0f 7e f1 ;movd ecx, xmm6
66 0f 7e f9 ;movd ecx, xmm7
In DMD 0.149 it produces this:
66 0F 7E C8 ;movd EAX, XMM1
66 0F 7E C9 ;movd ECX, XMM1
66 0F 7E CA ;movd EDX, XMM1
66 0F 7E CB ;movd EBX, XMM1
66 0F 7E CC ;movd ESP, XMM1
66 0F 7E CD ;movd EBP, XMM1
66 0F 7E CE ;movd ESI, XMM1
66 0F 7E CF ;movd EDI, XMM1
----------------------------------------
And this assembly code:
asm
{
movd EAX, XMM0;
movd ECX, XMM0;
movd EDX, XMM0;
movd EBX, XMM0;
movd ESI, XMM0;
movd EDI, XMM0;
movd EBP, XMM0;
movd ESI, XMM0;
}
In Visual C++ 2005 Express (and my own calculations) produces this machine code:
66 0f 7e c0 ;movd eax, xmm0
66 0f 7e c1 ;movd ecx, xmm0
66 0f 7e c2 ;movd edx, xmm0
66 0f 7e c3 ;movd ebx, xmm0
66 0f 7e c6 ;movd esi, xmm0
66 0f 7e c7 ;movd edi, xmm0
66 0f 7e c5 ;movd ebp, xmm0
66 0f 7e c6 ;movd esi, xmm0
In DMD 0.149 it produces this:
66 0F 7E C0 ;movd EAX, XMM0
66 0F 7E C8 ;movd EAX, XMM1
66 0F 7E D0 ;movd EAX, XMM2
66 0F 7E D8 ;movd EAX, XMM3
66 0F 7E F0 ;movd EAX, XMM6
66 0F 7E F8 ;movd EAX, XMM7
66 0F 7E E8 ;movd EAX, XMM5
66 0F 7E F0 ;movd EAX, XMM6
Interestingly, if you just use the EAX register then it works ok eg.
This assembly:
asm
{
movd EAX, XMM1;
movd EAX, XMM2;
movd EAX, XMM3;
movd EAX, XMM4;
movd EAX, XMM5;
movd EAX, XMM6;
movd EAX, XMM7;
}
Produces this which is correct:
66 0F 7E C0 ;movd EAX, XMM0
66 0F 7E C8 ;movd EAX, XMM1
66 0F 7E D0 ;movd EAX, XMM2
66 0F 7E D8 ;movd EAX, XMM3
66 0F 7E E0 ;movd EAX, XMM4
66 0F 7E E8 ;movd EAX, XMM5
66 0F 7E F0 ;movd EAX, XMM6
66 0F 7E F8 ;movd EAX, XMM7
-------------------------------------------
Proof:
import std.stdio;
int main(char[][] args)
{
asm
{
// make sure XMM1 is not 0
mov EAX,1;
movd XMM1, EAX; // moving from reg32 to XMM works ok
mov EAX,0; // ok EAX is now 0
// here is the test
// we move XMM0 to the ECX register
// (EAX should be in no way affected by this)
movd ECX, XMM0; // actual instruction executed will be movd EAX,XMM1;
// right let's look at EAX now
cmp EAX,0;
je good;
// oh dear
}
writefln("EAX is not 0. We have a problem.");
return 1;
good:
writefln("EAX = 0. Everything is alright with the world");
return 0;
}
I assume that as DMD and DMC use the same backend then this bug also affects
DMC.
Regards,
pmoore
Mar 14 2006
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
pmoore schrieb am 2006-03-14:
In the DMD code generator I believe the modrm reg and rm bits are being
interpreted the wrong way round for this instruction.
Consider this assembly code:
asm
{
movd ECX, XMM0;
movd ECX, XMM1;
movd ECX, XMM2;
movd ECX, XMM3;
movd ECX, XMM4;
movd ECX, XMM5;
movd ECX, XMM6;
movd ECX, XMM7;
}
In visual C++ 2005 express (and my own calculations) produces the following
machine code:
66 0f 7e c1 ;movd ecx, xmm0
66 0f 7e c9 ;movd ecx, xmm1
66 0f 7e d1 ;movd ecx, xmm2
66 0f 7e d9 ;movd ecx, xmm3
66 0f 7e e1 ;movd ecx, xmm4
66 0f 7e e9 ;movd ecx, xmm5
66 0f 7e f1 ;movd ecx, xmm6
66 0f 7e f9 ;movd ecx, xmm7
In DMD 0.149 it produces this:
66 0F 7E C8 ;movd EAX, XMM1
66 0F 7E C9 ;movd ECX, XMM1
66 0F 7E Chttp://dstress.kuehne.cn/;movd EDX, XMM1
66 0F 7E CB ;movd EBX, XMM1
66 0F 7E CC ;movd ESP, XMM1
66 0F 7E CD ;movd EBP, XMM1
66 0F 7E CE ;movd ESI, XMM1
66 0F 7E CF ;movd EDI, XMM1
----------------------------------------
And this assembly code:
asm
{
movd EAX, XMM0;
movd ECX, XMM0;
movd EDX, XMM0;
movd EBX, XMM0;
movd ESI, XMM0;
movd EDI, XMM0;
movd EBP, XMM0;
movd ESI, XMM0;
}
In Visual C++ 2005 Express (and my own calculations) produces this machine
code:
66 0f 7e c0 ;movd eax, xmm0
66 0f 7e c1 ;movd ecx, xmm0
66 0f 7e c2 ;movd edx, xmm0
66 0f 7e c3 ;movd ebx, xmm0
66 0f 7e c6 ;movd esi, xmm0
66 0f 7e c7 ;movd edi, xmm0
66 0f 7e c5 ;movd ebp, xmm0
66 0f 7e c6 ;movd esi, xmm0
In DMD 0.149 it produces this:
66 0F 7E C0 ;movd EAX, XMM0
66 0F 7E C8 ;movd EAX, XMM1
66 0F 7E D0 ;movd EAX, XMM2
66 0F 7E D8 ;movd EAX, XMM3
66 0F 7E F0 ;movd EAX, XMM6
66 0F 7E F8 ;movd EAX, XMM7
66 0F 7E E8 ;movd EAX, XMM5
66 0F 7E F0 ;movd EAX, XMM6
Interestingly, if you just use the EAX register then it works ok eg.
This assembly:
asm
{
movd EAX, XMM1;
movd EAX, XMM2;
movd EAX, XMM3;
movd EAX, XMM4;
movd EAX, XMM5;
movd EAX, XMM6;
movd EAX, XMM7;
}
Produces this which is correct:
66 0F 7E C0 ;movd EAX, XMM0
66 0F 7E C8 ;movd EAX, XMM1
66 0F 7E D0 ;movd EAX, XMM2
66 0F 7E D8 ;movd EAX, XMM3
66 0F 7E E0 ;movd EAX, XMM4
66 0F 7E E8 ;movd EAX, XMM5
66 0F 7E F0 ;movd EAX, XMM6
66 0F 7E F8 ;movd EAX, XMM7
-------------------------------------------
Proof:
import std.stdio;
int main(char[][] args)
{
asm
{
// make sure XMM1 is not 0
mov EAX,1;
movd XMM1, EAX; // moving from reg32 to XMM works ok
mov EAX,0; // ok EAX is now 0
// here is the test
// we move XMM0 to the ECX register
// (EAX should be in no way affected by this)
movd ECX, XMM0; // actual instruction executed will be movd EAX,XMM1;
// right let's look at EAX now
cmp EAX,0;
je good;
// oh dear
}
writefln("EAX is not 0. We have a problem.");
return 1;
good:
writefln("EAX = 0. Everything is alright with the world");
return 0;
}
I assume that as DMD and DMC use the same backend then this bug also affects
DMC.
Added to DStress as
http://dstress.kuehne.cn/run/a/asm_movd_02_A.d
http://dstress.kuehne.cn/run/a/asm_movd_02_B.d
http://dstress.kuehne.cn/run/a/asm_movd_02_C.d
http://dstress.kuehne.cn/run/a/asm_movd_02_D.d
http://dstress.kuehne.cn/run/a/asm_movd_02_E.d
http://dstress.kuehne.cn/run/a/asm_movd_02_F.d
http://dstress.kuehne.cn/run/a/asm_movd_02_G.d
http://dstress.kuehne.cn/run/a/asm_movd_02_H.d
http://dstress.kuehne.cn/run/a/asm_movd_02_I.d
http://dstress.kuehne.cn/run/a/asm_movd_02_J.d
http://dstress.kuehne.cn/run/a/asm_movd_02_K.d
http://dstress.kuehne.cn/run/a/asm_movd_02_L.d
http://dstress.kuehne.cn/run/a/asm_movd_02_M.d
http://dstress.kuehne.cn/run/a/asm_movd_02_N.d
http://dstress.kuehne.cn/run/a/asm_movd_02_O.d
http://dstress.kuehne.cn/run/a/asm_movd_02_P.d
http://dstress.kuehne.cn/run/a/asm_movd_03_A.d
http://dstress.kuehne.cn/run/a/asm_movd_03_B.d
http://dstress.kuehne.cn/run/a/asm_movd_03_C.d
http://dstress.kuehne.cn/run/a/asm_movd_03_D.d
http://dstress.kuehne.cn/run/a/asm_movd_03_E.d
http://dstress.kuehne.cn/run/a/asm_movd_03_F.d
http://dstress.kuehne.cn/run/a/asm_movd_03_G.d
http://dstress.kuehne.cn/run/a/asm_movd_03_H.d
http://dstress.kuehne.cn/run/a/asm_movd_03_I.d
http://dstress.kuehne.cn/run/a/asm_movd_03_J.d
http://dstress.kuehne.cn/run/a/asm_movd_03_K.d
http://dstress.kuehne.cn/run/a/asm_movd_03_L.d
http://dstress.kuehne.cn/run/a/asm_movd_03_M.d
http://dstress.kuehne.cn/run/a/asm_movd_03_N.d
http://dstress.kuehne.cn/run/a/asm_movd_03_O.d
http://dstress.kuehne.cn/run/a/asm_movd_03_P.d
http://dstress.kuehne.cn/run/a/asm_movd_04_A.d
http://dstress.kuehne.cn/run/a/asm_movd_04_B.d
http://dstress.kuehne.cn/run/a/asm_movd_04_C.d
http://dstress.kuehne.cn/run/a/asm_movd_04_D.d
http://dstress.kuehne.cn/run/a/asm_movd_04_E.d
http://dstress.kuehne.cn/run/a/asm_movd_04_F.d
http://dstress.kuehne.cn/run/a/asm_movd_04_G.d
http://dstress.kuehne.cn/run/a/asm_movd_04_H.d
http://dstress.kuehne.cn/run/a/asm_movd_04_I.d
http://dstress.kuehne.cn/run/a/asm_movd_04_J.d
http://dstress.kuehne.cn/run/a/asm_movd_04_K.d
http://dstress.kuehne.cn/run/a/asm_movd_04_L.d
http://dstress.kuehne.cn/run/a/asm_movd_04_M.d
http://dstress.kuehne.cn/run/a/asm_movd_04_N.d
http://dstress.kuehne.cn/run/a/asm_movd_04_O.d
http://dstress.kuehne.cn/run/a/asm_movd_04_P.d
http://dstress.kuehne.cn/run/a/asm_movd_05_A.d
http://dstress.kuehne.cn/run/a/asm_movd_05_B.d
http://dstress.kuehne.cn/run/a/asm_movd_05_C.d
http://dstress.kuehne.cn/run/a/asm_movd_05_D.d
http://dstress.kuehne.cn/run/a/asm_movd_05_E.d
http://dstress.kuehne.cn/run/a/asm_movd_05_F.d
http://dstress.kuehne.cn/run/a/asm_movd_05_G.d
http://dstress.kuehne.cn/run/a/asm_movd_05_H.d
http://dstress.kuehne.cn/run/a/asm_movd_05_I.d
http://dstress.kuehne.cn/run/a/asm_movd_05_J.d
http://dstress.kuehne.cn/run/a/asm_movd_05_K.d
http://dstress.kuehne.cn/run/a/asm_movd_05_L.d
http://dstress.kuehne.cn/run/a/asm_movd_05_M.d
http://dstress.kuehne.cn/run/a/asm_movd_05_N.d
http://dstress.kuehne.cn/run/a/asm_movd_05_O.d
http://dstress.kuehne.cn/run/a/asm_movd_05_P.d
Thomas
-----BEGIN PGP SIGNATURE-----
iD8DBQFEF09j3w+/yD4P9tIRAoEKAJ9h4U25u6rs+EK4tWY4+qP/Dw0wpACg0ZAN
DeiauaXzO+EhnkRPE9f/OcQ=
=SpvB
-----END PGP SIGNATURE-----
Mar 14 2006








Thomas Kuehne <thomas-dloop kuehne.cn>