| /* 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 386 assembly code. */ |
| |
| #include "config.h" |
| |
| .globl reflect.makeFuncStub |
| |
| #ifdef __ELF__ |
| .type reflect.makeFuncStub,@function |
| #endif |
| |
| reflect.makeFuncStub: |
| .LFB1: |
| |
| /* Go does not provide any equivalent to the regparm function |
| attribute, so on Go we do not need to worry about passing |
| parameters in registers. We just pass a pointer to the |
| arguments on the stack. |
| |
| We do need to pick up the return values, though, so we pass |
| a pointer to a struct that looks like this. |
| struct { |
| esp uint32 // 0x0 |
| eax uint32 // 0x4 |
| st0 uint64 // 0x8 |
| } |
| */ |
| |
| pushl %ebp |
| .LCFI0: |
| movl %esp, %ebp |
| .LCFI1: |
| pushl %ebx /* In case this is PIC. */ |
| subl $36, %esp /* Enough for args and to align stack. */ |
| .LCFI2: |
| |
| #ifdef __PIC__ |
| call __x86.get_pc_thunk.bx |
| addl $_GLOBAL_OFFSET_TABLE_, %ebx |
| #endif |
| |
| leal 8(%ebp), %eax /* Set esp field in struct. */ |
| movl %eax, -24(%ebp) |
| |
| #ifdef __PIC__ |
| call __go_get_closure@PLT |
| #else |
| call __go_get_closure |
| #endif |
| |
| movl %eax, 4(%esp) |
| |
| leal -24(%ebp), %eax |
| movl %eax, (%esp) |
| |
| #ifdef __PIC__ |
| call reflect.MakeFuncStubGo@PLT |
| #else |
| call reflect.MakeFuncStubGo |
| #endif |
| |
| /* Set return registers. */ |
| |
| movl -20(%ebp), %eax |
| fldl -16(%ebp) |
| |
| #ifdef __SSE2__ |
| /* In case we are compiling with -msseregparm. This won't work |
| correctly if only SSE1 is supported, but that seems unlikely. */ |
| movsd -16(%ebp), %xmm0 |
| #endif |
| |
| addl $36, %esp |
| popl %ebx |
| .LCFI3: |
| popl %ebp |
| .LCFI4: |
| ret |
| .LFE1: |
| #ifdef __ELF__ |
| .size reflect.makeFuncStub, . - reflect.makeFuncStub |
| #endif |
| |
| #ifdef __PIC__ |
| #ifdef HAVE_AS_COMDAT_GAS |
| .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat |
| #else |
| /* Sun as needs a different syntax. */ |
| .section .text.__x86.get_pc_thunk.bx%__x86.get_pc_thunk.bx,"ax",@progbits |
| .group __x86.get_pc_thunk.bx,.text.__x86.get_pc_thunk.bx%__x86.get_pc_thunk.bx,#comdat |
| #endif |
| .globl __x86.get_pc_thunk.bx |
| .hidden __x86.get_pc_thunk.bx |
| #ifdef __ELF__ |
| .type __x86.get_pc_thunk.bx, @function |
| #endif |
| __x86.get_pc_thunk.bx: |
| .LFB2: |
| movl (%esp), %ebx |
| ret |
| .LFE2: |
| #ifdef __ELF__ |
| .size __x86.get_pc_thunk.bx, . - __x86.get_pc_thunk.bx |
| #endif |
| #endif |
| |
| #ifdef __ELF__ |
| #if defined __PIC__ |
| # if defined __sun__ && defined __svr4__ |
| /* 32-bit Solaris 2/x86 uses datarel encoding for PIC. GNU ld before 2.22 |
| doesn't correctly sort .eh_frame_hdr with mixed encodings, so match this. */ |
| # define FDE_ENCODING 0x30 /* datarel */ |
| # define FDE_ENCODE(X) X@GOTOFF |
| # else |
| # define FDE_ENCODING 0x1b /* pcrel sdata4 */ |
| # if defined HAVE_AS_X86_PCREL |
| # define FDE_ENCODE(X) X-. |
| # else |
| # define FDE_ENCODE(X) X@rel |
| # endif |
| # endif |
| #else |
| # define FDE_ENCODING 0 /* absolute */ |
| # define FDE_ENCODE(X) X |
| #endif |
| |
| .section .eh_frame,EH_FRAME_FLAGS,@progbits |
| .Lframe1: |
| .long .LECIE1-.LSCIE1 /* Length of Common Information Entry */ |
| .LSCIE1: |
| .long 0x0 /* CIE Identifier Tag */ |
| .byte 0x1 /* CIE Version */ |
| .ascii "zR\0" /* CIE Augmentation */ |
| .byte 0x1 /* .uleb128 0x1; CIE Code Alignment Factor */ |
| .byte 0x7c /* .sleb128 -4; CIE Data Alignment Factor */ |
| .byte 0x8 /* CIE RA Column */ |
| .byte 0x1 /* .uleb128 0x1; Augmentation size */ |
| .byte FDE_ENCODING |
| .byte 0xc /* DW_CFA_def_cfa */ |
| .byte 0x4 /* .uleb128 0x4 */ |
| .byte 0x4 /* .uleb128 0x4 */ |
| .byte 0x88 /* DW_CFA_offset, column 0x8 */ |
| .byte 0x1 /* .uleb128 0x1 */ |
| .align 4 |
| .LECIE1: |
| .LSFDE1: |
| .long .LEFDE1-.LASFDE1 /* FDE Length */ |
| .LASFDE1: |
| .long .LASFDE1-.Lframe1 /* FDE CIE offset */ |
| .long FDE_ENCODE(.LFB1) /* FDE initial location */ |
| .long .LFE1-.LFB1 /* FDE address range */ |
| .byte 0x0 /* .uleb128 0x0; Augmentation size */ |
| .byte 0x4 /* DW_CFA_advance_loc4 */ |
| .long .LCFI0-.LFB1 |
| .byte 0xe /* DW_CFA_def_cfa_offset */ |
| .byte 0x8 /* .uleb128 0x8 */ |
| .byte 0x85 /* DW_CFA_offset, column 0x5 */ |
| .byte 0x2 /* .uleb128 0x2 */ |
| .byte 0x4 /* DW_CFA_advance_loc4 */ |
| .long .LCFI1-.LCFI0 |
| .byte 0xd /* DW_CFA_def_cfa_register */ |
| .byte 0x5 /* .uleb128 0x5 */ |
| .byte 0x4 /* DW_CFA_advance_loc4 */ |
| .long .LCFI2-.LCFI1 |
| .byte 0x83 /* .DW_CFA_offset, column 0x3 */ |
| .byte 0x3 /* .uleb128 0x3 */ |
| .byte 0x4 /* DW_CFA_advance_loc4 */ |
| .long .LCFI3-.LCFI2 |
| .byte 0xc3 /* DW_CFA_restore, column 0x3 */ |
| .byte 0x4 /* DW_CFA_advance_loc4 */ |
| .long .LCFI4-.LCFI3 |
| .byte 0xc5 /* DW_CFA_restore, column 0x5 */ |
| .byte 0xc /* DW_CFA_def_cfa */ |
| .byte 0x4 /* .uleb128 0x4 */ |
| .byte 0x4 /* .uleb128 0x4 */ |
| .align 4 |
| .LEFDE1: |
| #ifdef __PIC__ |
| .LSFDE2: |
| .long .LEFDE2-.LASFDE2 /* FDE Length */ |
| .LASFDE2: |
| .long .LASFDE2-.Lframe1 /* FDE CIE offset */ |
| .long FDE_ENCODE(.LFB2) /* FDE initial location */ |
| .long .LFE2-.LFB2 /* FDE address range */ |
| .byte 0x0 /* .uleb128 0x0; Augmentation size */ |
| .align 4 |
| .LEFDE2: |
| #endif /* __PIC__ */ |
| #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 |