Hello guys,<br><br> Thanks for your help when you are busing. <br> I am working on an open source project. It supports shader language and I want JIT feature, so LLVM is used.<br> But now I find the ABI & Calling Convention did not co-work with MSVC. For example, following code I have:<br>
<br><div style="margin-left:40px">struct float4 { float x, y, z, w; };<br>struct float4x4 { float4 x, y, z, w; };<br><br>float4 fetch_vs( float4x4* mat ){ return mat->y; }<br><br>Caller:<br><br>// ...<br>float4x4 mat; // Initialized<br>
float4 ret = fetch(mat); // fetch is JITed by LLVM<br>float4 ret_vs = fetch_vs(mat)<br>// ...<br><br>Callee(LLVM):<br><br>%vec4 = type { float, float, float, float }<br>%mat44 = type { %vec4, %vec4, %vec4, %vec4 }<br>define %vec4 @fetch( %mat44* %m ) {<br>
%matval = load %mat44* %m<br> %v2 = extractvalue %mat44 %matval, 2<br> ret %vec4 %v2<br> }<br clear="all"></div><br> But if it is implemented by LLVM and called the JIT-ed function in MSVC, the program will be <b>crashed</b>.<br>
I traced into the implementations, ASMs are:<br><br><b> Caller:</b><br> <br> float4x4 f;<br> float4 b = fetch(&f);<br> // Calling function. first address is a temporary result generated by caller. And secondary is the &f.<br>
013C1428 lea eax,[ebp-48h] <br> 013C142B push eax <br> 013C142C lea ecx,[ebp-138h] <br>
013C1432 push ecx <br> 013C1433 call fetch (13C11D6h) <br> 013C1438 add esp,8 <br><br> // Copy result to another temporary vairable.<br> 013C143B mov edx,dword ptr [eax] <br>
013C143D mov dword ptr [ebp-150h],edx <br>
013C1443 mov ecx,dword ptr [eax+4] <br> 013C1446 mov dword ptr [ebp-14Ch],ecx <br> 013C144C mov edx,dword ptr [eax+8] <br> 013C144F mov dword ptr [ebp-148h],edx <br> 013C1455 mov eax,dword ptr [eax+0Ch] <br>
013C1458 mov dword ptr [ebp-144h],eax <br> 013C145E mov ecx,dword ptr [ebp-150h] <br> <br> // Copy secondary temporary to variable 'b'<br> 013C1464 mov dword ptr [ebp-60h],ecx <br>
013C1467 mov edx,dword ptr [ebp-14Ch] <br>
013C146D mov dword ptr [ebp-5Ch],edx <br> 013C1470 mov eax,dword ptr [ebp-148h] <br> 013C1476 mov dword ptr [ebp-58h],eax <br> 013C1479 mov ecx,dword ptr [ebp-144h] <br>
013C147F mov dword ptr [ebp-54h],ecx<br><br><b> Callee( 'fetch_vs' MSVC ):</b><br><br> float4 __cdecl fetch( float4x4* mat ){<br><br>// Stack protection<br>002C13B0 push ebp <br>002C13B1 mov ebp,esp <br>
002C13B3 sub esp,0C0h <br>002C13B9 push ebx <br>002C13BA push esi <br>002C13BB push edi <br>002C13BC lea edi,[ebp-0C0h] <br>002C13C2 mov ecx,30h <br>002C13C7 mov eax,0CCCCCCCCh <br>
002C13CC rep stos dword ptr es:[edi] <br> return mat->y;<br><br>// Copy to address of first temporary variable.<br>002C13CE mov eax,dword ptr [mat] <br>002C13D1 add eax,10h <br>002C13D4 mov ecx,dword ptr [ebp+8] <br>
002C13D7 mov edx,dword ptr [eax] <br>002C13D9 mov dword ptr [ecx],edx <br>002C13DB mov edx,dword ptr [eax+4] <br>002C13DE mov dword ptr [ecx+4],edx <br>002C13E1 mov edx,dword ptr [eax+8] <br>
002C13E4 mov dword ptr [ecx+8],edx <br>002C13E7 mov eax,dword ptr [eax+0Ch] <br>002C13EA mov dword ptr [ecx+0Ch],eax <br>002C13ED mov eax,dword ptr [ebp+8] <br> }<br>002C13F0 pop edi <br>
002C13F1 pop esi <br>002C13F2 pop ebx <br>002C13F3 mov esp,ebp <br>002C13F5 pop ebp <br>002C13F6 ret <br><br> <b>Callee( 'fetch' LLVM ):</b><br> <br>010B0010 mov eax,dword ptr [esp+4] <br>
010B0014 mov ecx,dword ptr [esp+8] <br>010B0018 movss xmm0,dword ptr [ecx+1Ch] <br>010B001D movss dword ptr [eax+0Ch],xmm0 <br>010B0022 movss xmm0,dword ptr [ecx+18h] <br>010B0027 movss dword ptr [eax+8],xmm0 <br>
010B002C movss xmm0,dword ptr [ecx+10h] <br>010B0031 movss xmm1,dword ptr [ecx+14h] <br>010B0036 movss dword ptr [eax+4],xmm1 <br>010B003B movss dword ptr [eax],xmm0 <br>010B003F ret 4 // There are nothing push/pop in function and stack space is managed by caller, so why ret 4 is generated?<br>
<br>It will cause the stack unbalance before and after function call. the other code look like well.<br><br><b>Following is my questions:</b><br><br>1. Why it generates "ret 4" but not "ret" without modify esp?<br>
2. Does it doesn't support Microsoft Visual C++ compiler directly ?<br>3. I want to integrate LLVM JIT in MSVC, is it possible? what I will do, such as generate a adapter function ? Any porting document for it?<br>4. Does Clang support MS's call convention? If it does, how it work? I traced into it, but code is too large.<br>
5. Does it support Mingw directly ?<br>6. Does x64 work if your solution is applied ?<br><br>Thank you very much !<br><br>Best regards,<br>Your fans: Ye<br>-- <br>Ye Wu<br>CELL: <a href="tel:%2B86%2013671730301" value="+8613671730301" target="_blank">+86 13671730301</a><br>
<br>