1# Copyright 2013 The Go Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style
3# license that can be found in the LICENSE file.
4
5# MakeFunc amd64 assembly code.
6
7#include "config.h"
8
9	.global	reflect.makeFuncStub
10
11#ifdef __ELF__
12	.type	reflect.makeFuncStub,@function
13#endif
14
15reflect.makeFuncStub:
16.LFB1:
17
18	# Store all the parameter registers in a struct that looks
19	# like:
20	# struct {
21	#   rax uint64		// 0x0
22	#   rdi uint64		// 0x8
23	#   rsi uint64		// 0x10
24	#   rdx uint64		// 0x18
25	#   rcx uint64		// 0x20
26	#   r8 uint64		// 0x28
27	#   r9 uint64		// 0x30
28	#   rsp uint64		// 0x38 Pointer to arguments on stack.
29	#   xmm0 [2]uint64	// 0x40
30	#   xmm1 [2]uint64	// 0x50
31	#   xmm2 [2]uint64	// 0x60
32	#   xmm3 [2]uint64	// 0x70
33	#   xmm4 [2]uint64	// 0x80
34	#   xmm5 [2]uint64	// 0x90
35	#   xmm6 [2]uint64	// 0xa0
36	#   xmm7 [2]uint64	// 0xb0
37	# };
38
39	pushq	%rbp
40.LCFI0:
41	movq	%rsp, %rbp
42.LCFI1:
43
44	subq	$0xc0, %rsp		# Space for struct on stack.
45
46	movq	%rax, 0x0(%rsp)
47	movq	%rdi, 0x8(%rsp)
48	movq	%rsi, 0x10(%rsp)
49	movq	%rdx, 0x18(%rsp)
50	movq	%rcx, 0x20(%rsp)
51	movq	%r8, 0x28(%rsp)
52	movq	%r9, 0x30(%rsp)
53	leaq	16(%rbp), %rax
54	movq	%rax, 0x38(%rsp)
55	movdqa	%xmm0, 0x40(%rsp)
56	movdqa	%xmm1, 0x50(%rsp)
57	movdqa	%xmm2, 0x60(%rsp)
58	movdqa	%xmm3, 0x70(%rsp)
59	movdqa	%xmm4, 0x80(%rsp)
60	movdqa	%xmm5, 0x90(%rsp)
61	movdqa	%xmm6, 0xa0(%rsp)
62	movdqa	%xmm7, 0xb0(%rsp)
63
64	/* For MakeFunc functions that call recover.  */
65	movq	8(%rbp), %rdi
66#ifdef __PIC__
67	call	__go_makefunc_can_recover@PLT
68#else
69	call	__go_makefunc_can_recover
70#endif
71
72	# Get function type.
73#ifdef __PIC__
74	call	__go_get_closure@PLT
75#else
76	call	__go_get_closure
77#endif
78	movq	%rax, %rsi
79
80	movq	%rsp, %rdi
81
82#ifdef __PIC__
83	call	reflect.MakeFuncStubGo@PLT
84#else
85	call	reflect.MakeFuncStubGo
86#endif
87
88	/* MakeFunc functions can no longer call recover.  */
89#ifdef __PIC__
90	call __go_makefunc_returning@PLT
91#else
92	call __go_makefunc_returning
93#endif
94
95	# The structure will be updated with any return values.  Load
96	# all possible return registers before returning to the caller.
97
98	movq	0x0(%rsp), %rax
99	movq	0x18(%rsp), %rdx
100	movq	0x8(%rsp), %rdi
101	movq	0x10(%rsp), %rsi
102	movdqa	0x40(%rsp), %xmm0
103	movdqa	0x50(%rsp), %xmm1
104
105	# long double values are returned on the floating point stack,
106	# but we don't worry about that since Go doesn't have a long
107	# double type.
108
109	leave
110.LCFI2:
111
112	ret
113.LFE1:
114
115#ifdef __ELF__
116	.size	reflect.makeFuncStub, . - reflect.makeFuncStub
117#endif
118
119#ifdef __ELF__
120#ifdef HAVE_AS_X86_64_UNWIND_SECTION_TYPE
121	.section	.eh_frame,"a",@unwind
122#else
123	.section	.eh_frame,"a",@progbits
124#endif
125.Lframe1:
126	.long	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
127.LSCIE1:
128	.long	0x0		/* CIE Identifier Tag */
129	.byte	0x1		/* CIE Version */
130	.ascii "zR\0"		/* CIE Augmentation */
131	.uleb128 1		/* CIE Code Alignment Factor */
132	.sleb128 -8		/* CIE Data Alignment Factor */
133	.byte	0x10		/* CIE RA Column */
134	.uleb128 1		/* Augmentation size */
135	.byte	0x1b		/* FDE Encoding (pcrel sdata4) */
136	.byte	0xc		/* DW_CFA_def_cfa, %rsp offset 8 */
137	.uleb128 7
138	.uleb128 8
139	.byte	0x80+16		/* DW_CFA_offset, %rip offset 1*-8 */
140	.uleb128 1
141	.align 8
142.LECIE1:
143.LSFDE1:
144	.long	.LEFDE1-.LASFDE1	/* FDE Length */
145.LASFDE1:
146	.long	.LASFDE1-.Lframe1	/* FDE CIE offset */
147#if HAVE_AS_X86_PCREL
148	.long	.LFB1-.			/* FDE initial location */
149#else
150	.long	.LFB1@rel
151#endif
152	.long	.LFE1-.LFB1		/* FDE address range */
153	.uleb128 0x0			/* Augmentation size */
154	.byte	0x4			/* DW_CFA_advance_loc4 */
155	.long	.LCFI0-.LFB1
156	.byte	0xe			/* DW_CFA_def_cfa_offset */
157	.uleb128 16
158	.byte	0x86			/* DW_CFA_offset, column 0x6 */
159	.uleb128 2
160	.byte	0x4			/* DW_CFA_advance_loc4 */
161	.long	.LCFI1-.LCFI0
162	.byte	0xd			/* DW_CFA_def_cfa_register */
163	.uleb128 6
164	.byte	0x2			/* DW_CFA_advance_loc1 */
165	.byte	.LCFI2-.LCFI1
166	.byte	0xc			/* DW_CFA_def_cfa */
167	.uleb128 7
168	.uleb128 8
169	.align 8
170.LEFDE1:
171#endif /* __ELF__ */
172
173#if defined(__ELF__) && defined(__linux__)
174	.section	.note.GNU-stack,"",@progbits
175	.section	.note.GNU-split-stack,"",@progbits
176	.section	.note.GNU-no-split-stack,"",@progbits
177#endif
178