| 2517 | } |
| 2518 | |
| 2519 | void JitX86CodeGen::callHostFunction(void* address, const std::vector<DynParam>& params, bool restoreCache, bool saveCache) { |
| 2520 | U32 stackAdjust = 0; |
| 2521 | std::vector<U8> pushedRegs; |
| 2522 | |
| 2523 | for (int i = 0; i < NUMBER_OF_REGS; i++) { |
| 2524 | if (isVolitile[i] && isTmp[i] && regUsed[i]) { |
| 2525 | compiler.push(RN(i)); |
| 2526 | pushedRegs.push_back(i); |
| 2527 | } |
| 2528 | } |
| 2529 | if (saveCache) { |
| 2530 | callWriteCache(); |
| 2531 | } |
| 2532 | setParams(params); |
| 2533 | #ifdef BOXEDWINE_64 |
| 2534 | if ((pushedRegs.size() % 2) == 1) { |
| 2535 | stackAdjust = 8; |
| 2536 | } |
| 2537 | // part of the x64 windows ABI, shadow store |
| 2538 | #ifdef BOXEDWINE_MSVC |
| 2539 | compiler.sub(asmjit::x86::rsp, 32 + stackAdjust); |
| 2540 | #else |
| 2541 | if (stackAdjust) { |
| 2542 | compiler.push(PARAM_CALL_TMP); |
| 2543 | } |
| 2544 | #endif |
| 2545 | compiler.mov(PARAM_CALL_TMP, (U64)address); |
| 2546 | compiler.call(PARAM_CALL_TMP); |
| 2547 | #ifdef BOXEDWINE_MSVC |
| 2548 | compiler.add(asmjit::x86::rsp, 32 + stackAdjust); |
| 2549 | #else |
| 2550 | if (stackAdjust) { |
| 2551 | compiler.pop(PARAM_CALL_TMP); |
| 2552 | } |
| 2553 | #endif |
| 2554 | if (params.size() > 4) { |
| 2555 | kpanic("JitX86CodeGen::callHostFunction x64 doesn't support passing more than 4 parameters"); |
| 2556 | } |
| 2557 | #else |
| 2558 | compiler.call(address); |
| 2559 | |
| 2560 | if (params.size()) { |
| 2561 | compiler.add(regEsp, sizeof(void*) * params.size()); |
| 2562 | } |
| 2563 | #endif |
| 2564 | if (restoreCache) { |
| 2565 | callLoadCache(); |
| 2566 | } |
| 2567 | for (int i = (int)pushedRegs.size() - 1; i >= 0; i--) { |
| 2568 | compiler.pop(RN(pushedRegs[i])); |
| 2569 | } |
| 2570 | } |
| 2571 | |
| 2572 | void JitX86CodeGen::nakedCall(RegPtr reg) { |
| 2573 | compiler.call(RN(reg)); |