c++ - Calling convention mismatch for x64 floating point functions -


i'm having weird error. have 1 module compiled 1 compiler (msvc in case), calls code loaded module compiled seperate compiler (tcc).

the tcc code provides callback function both modules defined this:

typedef float( * scalefunc)(float value, float _min, float _max); 

the msvc code calls code this:

    finalvalue = extscale(val, _min, _max); 000007feecafcf52  mov         rax,qword ptr [this]   000007feecafcf5a  movss       xmm2,dword ptr [rax+0d0h]   000007feecafcf62  mov         rax,qword ptr [this]   000007feecafcf6a  movss       xmm1,dword ptr [rax+0cch]   000007feecafcf72  movss       xmm0,dword ptr [val]   000007feecafcf78  mov         rax,qword ptr [this]   000007feecafcf80  call        qword ptr [rax+0b8h]   000007feecafcf86  movss       dword ptr [finalvalue],xmm0  

and function compiled tcc looks this:

    float linear_scale(float value, float _min, float _max)      {          return value * (_max - _min) + _min;     } 0000000000503dc4  push        rbp   0000000000503dc5  mov         rbp,rsp   0000000000503dc8  sub         rsp,0   0000000000503dcf  mov         qword ptr [rbp+10h],rcx   0000000000503dd3  mov         qword ptr [rbp+18h],rdx   0000000000503dd7  mov         qword ptr [rbp+20h],r8   0000000000503ddb  movd        xmm0,dword ptr [rbp+20h]   0000000000503de0  subss       xmm0,dword ptr [rbp+18h]   0000000000503de5  movq        xmm1,xmm0   0000000000503de9  movd        xmm0,dword ptr [rbp+10h]   0000000000503dee  mulss       xmm0,xmm1   0000000000503df2  addss       xmm0,dword ptr [rbp+18h]   0000000000503df7  jmp         0000000000503dfc   0000000000503dfc  leave   0000000000503dfd  ret   

it seems tcc expects arguments in integer registers r6 r8, while msvc puts them in sse registers. thought x64 (on windows) defines 1 common calling convention? going on here, , how can enforce same model on both platforms?

the same code works correctly in 32-bit mode. weirdly enough, on osx (where other code compiled llvm) works in both modes (32 , 64-bit). ill see if can fetch assembly there, later.

---- edit ----

i have created working solution. however, without doubt, dirtiest hack i've ever made (bar questionable inline assembly, unfortunately isn't available on msvc 64-bit :)).

// passes first 3 floating point arguments in r6 r8 template<typename ssetype>     ssetype tccassemblyhelper(scalefunc cb, ssetype val, ssetype _min, ssetype _max)     {         ssetype xmm0(val), xmm1(_min), xmm2(_max);         long long rcx, rdx, r8;         rcx = *(long long*)&xmm0;         rdx = *(long long*)&xmm1;         r8 = *(long long*)&xmm2;          typedef float(*intermedfunc)(long long rcx, long long rdx, long long r8);          intermedfunc helperfunc = reinterpret_cast<intermedfunc>(cb);         return helperfunc(rcx, rdx, r8);     } 


Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -