X86 implementation
| 1781 | #if !defined(__CELLOS_LV2__) && !defined(_M_X64) |
| 1782 | // X86 implementation |
| 1783 | bool Executor::RunExternalFunction(unsigned int funcID, unsigned int extraPopDW) |
| 1784 | { |
| 1785 | unsigned int dwordsToPop = (exFunctions[funcID].bytesToPop >> 2); |
| 1786 | //unsigned int bytesToPop = exFunctions[funcID].bytesToPop; |
| 1787 | void* fPtr = exFunctions[funcID].funcPtr; |
| 1788 | unsigned int retType = exFunctions[funcID].retType; |
| 1789 | |
| 1790 | unsigned int *stackStart = (genStackPtr + dwordsToPop - 1); |
| 1791 | for(unsigned int i = 0; i < dwordsToPop; i++) |
| 1792 | { |
| 1793 | #ifdef __GNUC__ |
| 1794 | asm("movl %0, %%eax"::"r"(stackStart):"%eax"); |
| 1795 | asm("pushl (%eax)"); |
| 1796 | #else |
| 1797 | __asm{ mov eax, dword ptr[stackStart] } |
| 1798 | __asm{ push dword ptr[eax] } |
| 1799 | #endif |
| 1800 | stackStart--; |
| 1801 | } |
| 1802 | unsigned int *newStackPtr = genStackPtr + dwordsToPop + extraPopDW; |
| 1803 | |
| 1804 | switch(retType) |
| 1805 | { |
| 1806 | case ExternFuncInfo::RETURN_VOID: |
| 1807 | ((void (*)())fPtr)(); |
| 1808 | break; |
| 1809 | case ExternFuncInfo::RETURN_INT: |
| 1810 | newStackPtr -= 1; |
| 1811 | *newStackPtr = ((int (*)())fPtr)(); |
| 1812 | break; |
| 1813 | case ExternFuncInfo::RETURN_DOUBLE: |
| 1814 | newStackPtr -= 2; |
| 1815 | *(double*)newStackPtr = ((double (*)())fPtr)(); |
| 1816 | break; |
| 1817 | case ExternFuncInfo::RETURN_LONG: |
| 1818 | newStackPtr -= 2; |
| 1819 | *(long long*)newStackPtr = ((long long (*)())fPtr)(); |
| 1820 | break; |
| 1821 | #ifdef NULLC_COMPLEX_RETURN |
| 1822 | case ExternFuncInfo::RETURN_UNKNOWN: |
| 1823 | { |
| 1824 | unsigned int ret[128]; |
| 1825 | unsigned int *ptr = &ret[0]; |
| 1826 | asm("movl %0, %%eax"::"r"(ptr):"%eax"); |
| 1827 | asm("pushl %eax"); |
| 1828 | |
| 1829 | ((void (*)())fPtr)(); |
| 1830 | |
| 1831 | // adjust new stack top |
| 1832 | newStackPtr -= exFunctions[funcID].returnShift; |
| 1833 | // copy return value on top of the stack |
| 1834 | memcpy(newStackPtr, ret, exFunctions[funcID].returnShift * 4); |
| 1835 | } |
| 1836 | break; |
| 1837 | #endif |
| 1838 | } |
| 1839 | genStackPtr = newStackPtr; |
| 1840 | #ifdef __GNUC__ |