| 70 | __attribute__((optimize(0))) |
| 71 | #endif |
| 72 | X64_CallFunction(const asQWORD *args, int cnt, funcptr_t func, asQWORD &retQW2, bool returnFloat) |
| 73 | { |
| 74 | // Need to flag the variable as volatile so the compiler doesn't optimize out the variable |
| 75 | volatile asQWORD retQW1 = 0; |
| 76 | |
| 77 | // Reference: http://www.x86-64.org/documentation/abi.pdf |
| 78 | |
| 79 | __asm__ __volatile__ ( |
| 80 | |
| 81 | " movq %0, %%rcx \n" // rcx = cnt |
| 82 | " movq %1, %%r10 \n" // r10 = args |
| 83 | " movq %2, %%r11 \n" // r11 = func |
| 84 | |
| 85 | // Backup stack pointer in R15 that is guaranteed to maintain its value over function calls |
| 86 | " movq %%rsp, %%r15 \n" |
| 87 | #if defined(__clang__) && defined(__OPTIMIZE__) |
| 88 | // Make sure the stack unwind logic knows we've backed up the stack pointer in register r15 |
| 89 | // This should only be done if any optimization is done. If no optimization (-O0) is used, |
| 90 | // then the compiler already backups the rsp before entering the inline assembler code |
| 91 | " .cfi_def_cfa_register r15 \n" |
| 92 | #endif |
| 93 | |
| 94 | // Skip the first 128 bytes on the stack frame, called "red zone", |
| 95 | // that might be used by the compiler to store temporary values |
| 96 | " sub $128, %%rsp \n" |
| 97 | |
| 98 | // Make sure the stack pointer will be aligned to 16 bytes when the function is called |
| 99 | " movq %%rcx, %%rdx \n" |
| 100 | " salq $3, %%rdx \n" |
| 101 | " movq %%rsp, %%rax \n" |
| 102 | " sub %%rdx, %%rax \n" |
| 103 | " and $15, %%rax \n" |
| 104 | " sub %%rax, %%rsp \n" |
| 105 | |
| 106 | // Push the stack parameters, i.e. the arguments that won't be loaded into registers |
| 107 | " movq %%rcx, %%rsi \n" |
| 108 | " testl %%esi, %%esi \n" |
| 109 | " jle endstack \n" |
| 110 | " subl $1, %%esi \n" |
| 111 | " xorl %%edx, %%edx \n" |
| 112 | " leaq 8(, %%rsi, 8), %%rcx \n" |
| 113 | "loopstack: \n" |
| 114 | " movq 112(%%r10, %%rdx), %%rax \n" |
| 115 | " pushq %%rax \n" |
| 116 | " addq $8, %%rdx \n" |
| 117 | " cmpq %%rcx, %%rdx \n" |
| 118 | " jne loopstack \n" |
| 119 | "endstack: \n" |
| 120 | |
| 121 | // Populate integer and floating point parameters |
| 122 | " movq %%r10, %%rax \n" |
| 123 | " mov (%%rax), %%rdi \n" |
| 124 | " mov 8(%%rax), %%rsi \n" |
| 125 | " mov 16(%%rax), %%rdx \n" |
| 126 | " mov 24(%%rax), %%rcx \n" |
| 127 | " mov 32(%%rax), %%r8 \n" |
| 128 | " mov 40(%%rax), %%r9 \n" |
| 129 | " add $48, %%rax \n" |
no outgoing calls
no test coverage detected