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>