static void GNUC3_ATTRIBUTE()

in rts/StgCRun.c [367:547]


static void GNUC3_ATTRIBUTE(used)
StgRunIsImplementedInAssembler(void)
{
    __asm__ volatile (
        /*
         * save callee-saves registers on behalf of the STG code.
         */
        STG_GLOBAL STG_RUN "\n"
#if !defined(mingw32_HOST_OS)
        STG_HIDDEN STG_RUN "\n"
#endif
        STG_RUN ":\n\t"
        "subq %1, %%rsp\n\t"
        "movq %%rsp, %%rax\n\t"
        "subq %0, %%rsp\n\t"
        "movq %%rbx,0(%%rax)\n\t"
        "movq %%rbp,8(%%rax)\n\t"
        "movq %%r12,16(%%rax)\n\t"
        "movq %%r13,24(%%rax)\n\t"
        "movq %%r14,32(%%rax)\n\t"
        "movq %%r15,40(%%rax)\n\t"
#if defined(mingw32_HOST_OS)
        /*
         * Additional callee saved registers on Win64. This must match
         * callClobberedRegisters in compiler/nativeGen/X86/Regs.hs as
         * both represent the Win64 calling convention.
         */
        "movq %%rdi,48(%%rax)\n\t"
        "movq %%rsi,56(%%rax)\n\t"
        "movq %%xmm6,  64(%%rax)\n\t"
        "movq %%xmm7,  72(%%rax)\n\t"
        "movq %%xmm8,  80(%%rax)\n\t"
        "movq %%xmm9,  88(%%rax)\n\t"
        "movq %%xmm10, 96(%%rax)\n\t"
        "movq %%xmm11,104(%%rax)\n\t"
        "movq %%xmm12,112(%%rax)\n\t"
        "movq %%xmm13,120(%%rax)\n\t"
        "movq %%xmm14,128(%%rax)\n\t"
        "movq %%xmm15,136(%%rax)\n\t"
#endif

#if !defined(darwin_HOST_OS)
        /*
         * Let the unwinder know where we saved the registers
         * See Note [Unwinding foreign exports on x86-64].
         *
         * N.B. We don't support unwinding on Darwin due to
         * various toolchain insanity.
         */
        ".cfi_def_cfa rsp, 0\n\t"
        ".cfi_offset rbx, %c2\n\t"
        ".cfi_offset rbp, %c3\n\t"
        ".cfi_offset r12, %c4\n\t"
        ".cfi_offset r13, %c5\n\t"
        ".cfi_offset r14, %c6\n\t"
        ".cfi_offset r15, %c7\n\t"
        ".cfi_offset rip, %c8\n\t"
        ".cfi_escape " // DW_CFA_val_expression is not expressible otherwise
          "0x16, " // DW_CFA_val_expression
          "0x07, " // register num 7 - rsp
          "0x04, " // block length
          "0x77, " // DW_OP_breg7 - signed LEB128 offset from rsp
#define RSP_DELTA (RESERVED_C_STACK_BYTES + STG_RUN_STACK_FRAME_SIZE + 8)
          "%c9" // signed LEB128 encoded delta - byte 1
#if (RSP_DELTA >> 7) > 0
          ", %c10" // signed LEB128 encoded delta - byte 2
#endif

#if (RSP_DELTA >> 14) > 0
          ", %c11" // signed LEB128 encoded delta - byte 3
#endif

#if (RSP_DELTA >> 21) > 0
          ", %c12" // signed LEB128 encoded delta - byte 4
#endif

#if (RSP_DELTA >> 28) > 0
#error "RSP_DELTA too big"
#endif
          "\n\t"
#endif /* !defined(darwin_HOST_OS) */

        /*
         * Set BaseReg
         */
#if defined(mingw32_HOST_OS)
        "movq %%rdx,%%r13\n\t"
#else
        "movq %%rsi,%%r13\n\t"
#endif
        /*
         * grab the function argument from the stack, and jump to it.
         */
#if defined(mingw32_HOST_OS)
        "movq %%rcx,%%rax\n\t"
#else
        "movq %%rdi,%%rax\n\t"
#endif

        STG_GLOBAL xstr(STG_RUN_JMP) "\n"
#if !defined(mingw32_HOST_OS)
        STG_HIDDEN xstr(STG_RUN_JMP) "\n"
#endif
#if HAVE_SUBSECTIONS_VIA_SYMBOLS
        // If we have deadstripping enabled and a label is detected as unused
        // the code gets nop'd out.
        ".no_dead_strip " xstr(STG_RUN_JMP) "\n"
#endif
        xstr(STG_RUN_JMP) ":\n\t"
        "jmp *%%rax\n\t"

        ".globl " STG_RETURN "\n"
         STG_RETURN ":\n\t"

        "movq %%rbx, %%rax\n\t"   /* Return value in R1  */

        /*
         * restore callee-saves registers.  (Don't stomp on %%rax!)
         */
        "addq %0, %%rsp\n\t"
        "movq 0(%%rsp),%%rbx\n\t"       /* restore the registers saved above */
        "movq 8(%%rsp),%%rbp\n\t"
        "movq 16(%%rsp),%%r12\n\t"
        "movq 24(%%rsp),%%r13\n\t"
        "movq 32(%%rsp),%%r14\n\t"
        "movq 40(%%rsp),%%r15\n\t"
#if defined(mingw32_HOST_OS)
        "movq  48(%%rsp),%%rdi\n\t"
        "movq  56(%%rsp),%%rsi\n\t"
        "movq  64(%%rsp),%%xmm6\n\t"
        "movq  72(%%rax),%%xmm7\n\t"
        "movq  80(%%rax),%%xmm8\n\t"
        "movq  88(%%rax),%%xmm9\n\t"
        "movq  96(%%rax),%%xmm10\n\t"
        "movq 104(%%rax),%%xmm11\n\t"
        "movq 112(%%rax),%%xmm12\n\t"
        "movq 120(%%rax),%%xmm13\n\t"
        "movq 128(%%rax),%%xmm14\n\t"
        "movq 136(%%rax),%%xmm15\n\t"
#endif
        "addq %1, %%rsp\n\t"
        "retq"

        :
        : "i"(RESERVED_C_STACK_BYTES),
          "i"(STG_RUN_STACK_FRAME_SIZE /* stack frame size */),
          "i"(RESERVED_C_STACK_BYTES /* rbx relative to cfa (rsp) */),
          "i"(RESERVED_C_STACK_BYTES + 8 /* rbp relative to cfa (rsp) */),
          "i"(RESERVED_C_STACK_BYTES + 16 /* r12 relative to cfa (rsp) */),
          "i"(RESERVED_C_STACK_BYTES + 24 /* r13 relative to cfa (rsp) */),
          "i"(RESERVED_C_STACK_BYTES + 32 /* r14 relative to cfa (rsp) */),
          "i"(RESERVED_C_STACK_BYTES + 40 /* r15 relative to cfa (rsp) */),
          "i"(RESERVED_C_STACK_BYTES + STG_RUN_STACK_FRAME_SIZE
              /* rip relative to cfa */)

#if !defined(darwin_HOST_OS)
          , "i"((RSP_DELTA & 127) | (128 * ((RSP_DELTA >> 7) > 0)))
            /* signed LEB128-encoded delta from rsp - byte 1 */
#if (RSP_DELTA >> 7) > 0
          , "i"(((RSP_DELTA >> 7) & 127) | (128 * ((RSP_DELTA >> 14) > 0)))
            /* signed LEB128-encoded delta from rsp - byte 2 */
#endif

#if (RSP_DELTA >> 14) > 0
          , "i"(((RSP_DELTA >> 14) & 127) | (128 * ((RSP_DELTA >> 21) > 0)))
            /* signed LEB128-encoded delta from rsp - byte 3 */
#endif

#if (RSP_DELTA >> 21) > 0
          , "i"(((RSP_DELTA >> 21) & 127) | (128 * ((RSP_DELTA >> 28) > 0)))
            /* signed LEB128-encoded delta from rsp - byte 4 */
#endif
#undef RSP_DELTA

#endif /* !defined(darwin_HOST_OS) */

        );
        /*
         * See Note [Stack Alignment on X86]
         */
}