diff options
Diffstat (limited to 'libgo/go/reflect/makefunc_amd64.S')
-rw-r--r-- | libgo/go/reflect/makefunc_amd64.S | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/libgo/go/reflect/makefunc_amd64.S b/libgo/go/reflect/makefunc_amd64.S new file mode 100644 index 00000000000..88302eee1b2 --- /dev/null +++ b/libgo/go/reflect/makefunc_amd64.S @@ -0,0 +1,177 @@ +# 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 |