March 14, 2006 Inline assembly movd reg32/mem, xmmreg instruction produces incorrect machine code | ||||
---|---|---|---|---|
| ||||
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 |
March 14, 2006 Re: Inline assembly movd reg32/mem, xmmreg instruction produces incorrect machine code | ||||
---|---|---|---|---|
| ||||
Posted in reply to pmoore Attachments: | 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 |
Copyright © 1999-2021 by the D Language Foundation