| # Copyright 2013 The Go Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style |
| # license that can be found in the LICENSE file. |
| |
| # MakeFunc amd64 assembly code. |
| |
| #include "config.h" |
| |
| .global reflect.makeFuncStub |
| |
| #ifdef __ELF__ |
| .type reflect.makeFuncStub,@function |
| #endif |
| |
| reflect.makeFuncStub: |
| .LFB1: |
| |
| # Store all the parameter registers in a struct that looks |
| # like: |
| # struct { |
| # rax uint64 // 0x0 |
| # rdi uint64 // 0x8 |
| # rsi uint64 // 0x10 |
| # rdx uint64 // 0x18 |
| # rcx uint64 // 0x20 |
| # r8 uint64 // 0x28 |
| # r9 uint64 // 0x30 |
| # rsp uint64 // 0x38 Pointer to arguments on stack. |
| # xmm0 [2]uint64 // 0x40 |
| # xmm1 [2]uint64 // 0x50 |
| # xmm2 [2]uint64 // 0x60 |
| # xmm3 [2]uint64 // 0x70 |
| # xmm4 [2]uint64 // 0x80 |
| # xmm5 [2]uint64 // 0x90 |
| # xmm6 [2]uint64 // 0xa0 |
| # xmm7 [2]uint64 // 0xb0 |
| # }; |
| |
| pushq %rbp |
| .LCFI0: |
| movq %rsp, %rbp |
| .LCFI1: |
| |
| subq $0xc0, %rsp # Space for struct on stack. |
| |
| movq %rax, 0x0(%rsp) |
| movq %rdi, 0x8(%rsp) |
| movq %rsi, 0x10(%rsp) |
| movq %rdx, 0x18(%rsp) |
| movq %rcx, 0x20(%rsp) |
| movq %r8, 0x28(%rsp) |
| movq %r9, 0x30(%rsp) |
| leaq 16(%rbp), %rax |
| movq %rax, 0x38(%rsp) |
| movdqa %xmm0, 0x40(%rsp) |
| movdqa %xmm1, 0x50(%rsp) |
| movdqa %xmm2, 0x60(%rsp) |
| movdqa %xmm3, 0x70(%rsp) |
| movdqa %xmm4, 0x80(%rsp) |
| movdqa %xmm5, 0x90(%rsp) |
| movdqa %xmm6, 0xa0(%rsp) |
| movdqa %xmm7, 0xb0(%rsp) |
| |
| /* For MakeFunc functions that call recover. */ |
| movq 8(%rbp), %rdi |
| #ifdef __PIC__ |
| call __go_makefunc_can_recover@PLT |
| #else |
| call __go_makefunc_can_recover |
| #endif |
| |
| # Get function type. |
| #ifdef __PIC__ |
| call __go_get_closure@PLT |
| #else |
| call __go_get_closure |
| #endif |
| movq %rax, %rsi |
| |
| movq %rsp, %rdi |
| |
| #ifdef __PIC__ |
| call reflect.MakeFuncStubGo@PLT |
| #else |
| call reflect.MakeFuncStubGo |
| #endif |
| |
| /* MakeFunc functions can no longer call recover. */ |
| #ifdef __PIC__ |
| call __go_makefunc_returning@PLT |
| #else |
| call __go_makefunc_returning |
| #endif |
| |
| # The structure will be updated with any return values. Load |
| # all possible return registers before returning to the caller. |
| |
| movq 0x0(%rsp), %rax |
| movq 0x18(%rsp), %rdx |
| movq 0x8(%rsp), %rdi |
| movq 0x10(%rsp), %rsi |
| movdqa 0x40(%rsp), %xmm0 |
| movdqa 0x50(%rsp), %xmm1 |
| |
| # long double values are returned on the floating point stack, |
| # but we don't worry about that since Go doesn't have a long |
| # double type. |
| |
| leave |
| .LCFI2: |
| |
| ret |
| .LFE1: |
| |
| #ifdef __ELF__ |
| .size reflect.makeFuncStub, . - reflect.makeFuncStub |
| #endif |
| |
| #ifdef __ELF__ |
| #ifdef HAVE_AS_X86_64_UNWIND_SECTION_TYPE |
| .section .eh_frame,"a",@unwind |
| #else |
| .section .eh_frame,"a",@progbits |
| #endif |
| .Lframe1: |
| .long .LECIE1-.LSCIE1 /* Length of Common Information Entry */ |
| .LSCIE1: |
| .long 0x0 /* CIE Identifier Tag */ |
| .byte 0x1 /* CIE Version */ |
| .ascii "zR\0" /* CIE Augmentation */ |
| .uleb128 1 /* CIE Code Alignment Factor */ |
| .sleb128 -8 /* CIE Data Alignment Factor */ |
| .byte 0x10 /* CIE RA Column */ |
| .uleb128 1 /* Augmentation size */ |
| .byte 0x1b /* FDE Encoding (pcrel sdata4) */ |
| .byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */ |
| .uleb128 7 |
| .uleb128 8 |
| .byte 0x80+16 /* DW_CFA_offset, %rip offset 1*-8 */ |
| .uleb128 1 |
| .align 8 |
| .LECIE1: |
| .LSFDE1: |
| .long .LEFDE1-.LASFDE1 /* FDE Length */ |
| .LASFDE1: |
| .long .LASFDE1-.Lframe1 /* FDE CIE offset */ |
| #if HAVE_AS_X86_PCREL |
| .long .LFB1-. /* FDE initial location */ |
| #else |
| .long .LFB1@rel |
| #endif |
| .long .LFE1-.LFB1 /* FDE address range */ |
| .uleb128 0x0 /* Augmentation size */ |
| .byte 0x4 /* DW_CFA_advance_loc4 */ |
| .long .LCFI0-.LFB1 |
| .byte 0xe /* DW_CFA_def_cfa_offset */ |
| .uleb128 16 |
| .byte 0x86 /* DW_CFA_offset, column 0x6 */ |
| .uleb128 2 |
| .byte 0x4 /* DW_CFA_advance_loc4 */ |
| .long .LCFI1-.LCFI0 |
| .byte 0xd /* DW_CFA_def_cfa_register */ |
| .uleb128 6 |
| .byte 0x2 /* DW_CFA_advance_loc1 */ |
| .byte .LCFI2-.LCFI1 |
| .byte 0xc /* DW_CFA_def_cfa */ |
| .uleb128 7 |
| .uleb128 8 |
| .align 8 |
| .LEFDE1: |
| #endif /* __ELF__ */ |
| |
| #if defined(__ELF__) && defined(__linux__) |
| .section .note.GNU-stack,"",@progbits |
| .section .note.GNU-split-stack,"",@progbits |
| .section .note.GNU-no-split-stack,"",@progbits |
| #endif |