]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/xray/xray_trampoline_x86_64.S
Merge clang, llvm, lld, lldb, compiler-rt and libc++ 5.0.0 release.
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / xray / xray_trampoline_x86_64.S
1 //===-- xray_trampoline_x86.s -----------------------------------*- ASM -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of XRay, a dynamic runtime instrumentation system.
11 //
12 // This implements the X86-specific assembler for the trampolines.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "../builtins/assembly.h"
17
18 .macro SAVE_REGISTERS
19         subq $192, %rsp
20         .cfi_def_cfa_offset 200
21         // At this point, the stack pointer should be aligned to an 8-byte boundary,
22         // because any call instructions that come after this will add another 8
23         // bytes and therefore align it to 16-bytes.
24         movq %rbp, 184(%rsp)
25         movupd  %xmm0, 168(%rsp)
26         movupd  %xmm1, 152(%rsp)
27         movupd  %xmm2, 136(%rsp)
28         movupd  %xmm3, 120(%rsp)
29         movupd  %xmm4, 104(%rsp)
30         movupd  %xmm5, 88(%rsp)
31         movupd  %xmm6, 72(%rsp)
32         movupd  %xmm7, 56(%rsp)
33         movq    %rdi, 48(%rsp)
34         movq    %rax, 40(%rsp)
35         movq    %rdx, 32(%rsp)
36         movq    %rsi, 24(%rsp)
37         movq    %rcx, 16(%rsp)
38         movq    %r8, 8(%rsp)
39         movq    %r9, 0(%rsp)
40 .endm
41
42 .macro RESTORE_REGISTERS
43         movq  184(%rsp), %rbp
44         movupd  168(%rsp), %xmm0
45         movupd  152(%rsp), %xmm1
46         movupd  136(%rsp), %xmm2
47         movupd  120(%rsp), %xmm3
48         movupd  104(%rsp), %xmm4
49         movupd  88(%rsp), %xmm5
50         movupd  72(%rsp) , %xmm6
51         movupd  56(%rsp) , %xmm7
52         movq    48(%rsp), %rdi
53         movq    40(%rsp), %rax
54         movq    32(%rsp), %rdx
55         movq    24(%rsp), %rsi
56         movq    16(%rsp), %rcx
57         movq    8(%rsp), %r8
58         movq    0(%rsp), %r9
59         addq    $192, %rsp
60         .cfi_def_cfa_offset 8
61 .endm
62
63         .text
64         .file "xray_trampoline_x86.S"
65
66 //===----------------------------------------------------------------------===//
67
68         .globl __xray_FunctionEntry
69         .align 16, 0x90
70         .type __xray_FunctionEntry,@function
71
72 __xray_FunctionEntry:
73         .cfi_startproc
74         SAVE_REGISTERS
75
76         // This load has to be atomic, it's concurrent with __xray_patch().
77         // On x86/amd64, a simple (type-aligned) MOV instruction is enough.
78         movq    _ZN6__xray19XRayPatchedFunctionE(%rip), %rax
79         testq   %rax, %rax
80         je      .Ltmp0
81
82         // The patched function prolog puts its xray_instr_map index into %r10d.
83         movl    %r10d, %edi
84         xor     %esi,%esi
85         callq   *%rax
86 .Ltmp0:
87         RESTORE_REGISTERS
88         retq
89 .Ltmp1:
90         .size __xray_FunctionEntry, .Ltmp1-__xray_FunctionEntry
91         .cfi_endproc
92
93 //===----------------------------------------------------------------------===//
94
95         .globl __xray_FunctionExit
96         .align 16, 0x90
97         .type __xray_FunctionExit,@function
98 __xray_FunctionExit:
99         .cfi_startproc
100         // Save the important registers first. Since we're assuming that this
101         // function is only jumped into, we only preserve the registers for
102         // returning.
103         subq    $56, %rsp
104         .cfi_def_cfa_offset 64
105         movq  %rbp, 48(%rsp)
106         movupd  %xmm0, 32(%rsp)
107         movupd  %xmm1, 16(%rsp)
108         movq    %rax, 8(%rsp)
109         movq    %rdx, 0(%rsp)
110         movq    _ZN6__xray19XRayPatchedFunctionE(%rip), %rax
111         testq %rax,%rax
112         je      .Ltmp2
113
114         movl    %r10d, %edi
115         movl    $1, %esi
116         callq   *%rax
117 .Ltmp2:
118         // Restore the important registers.
119         movq  48(%rsp), %rbp
120         movupd  32(%rsp), %xmm0
121         movupd  16(%rsp), %xmm1
122         movq    8(%rsp), %rax
123         movq    0(%rsp), %rdx
124         addq    $56, %rsp
125         .cfi_def_cfa_offset 8
126         retq
127 .Ltmp3:
128         .size __xray_FunctionExit, .Ltmp3-__xray_FunctionExit
129         .cfi_endproc
130
131 //===----------------------------------------------------------------------===//
132
133         .global __xray_FunctionTailExit
134         .align 16, 0x90
135         .type __xray_FunctionTailExit,@function
136 __xray_FunctionTailExit:
137         .cfi_startproc
138         // Save the important registers as in the entry trampoline, but indicate that
139         // this is an exit. In the future, we will introduce a new entry type that
140         // differentiates between a normal exit and a tail exit, but we'd have to do
141         // this and increment the version number for the header.
142         SAVE_REGISTERS
143
144         movq    _ZN6__xray19XRayPatchedFunctionE(%rip), %rax
145         testq %rax,%rax
146         je      .Ltmp4
147
148         movl    %r10d, %edi
149         movl    $1, %esi
150         callq   *%rax
151
152 .Ltmp4:
153         RESTORE_REGISTERS
154         retq
155 .Ltmp5:
156         .size __xray_FunctionTailExit, .Ltmp5-__xray_FunctionTailExit
157         .cfi_endproc
158
159 //===----------------------------------------------------------------------===//
160
161         .globl __xray_ArgLoggerEntry
162         .align 16, 0x90
163         .type __xray_ArgLoggerEntry,@function
164 __xray_ArgLoggerEntry:
165         .cfi_startproc
166         SAVE_REGISTERS
167
168         // Again, these function pointer loads must be atomic; MOV is fine.
169         movq    _ZN6__xray13XRayArgLoggerE(%rip), %rax
170         testq   %rax, %rax
171         jne     .Larg1entryLog
172
173         // If [arg1 logging handler] not set, defer to no-arg logging.
174         movq    _ZN6__xray19XRayPatchedFunctionE(%rip), %rax
175         testq   %rax, %rax
176         je      .Larg1entryFail
177
178 .Larg1entryLog:
179
180   // First argument will become the third
181         movq    %rdi, %rdx
182
183   // XRayEntryType::ENTRY into the second
184         xorq    %rsi, %rsi
185
186         // 32-bit function ID becomes the first
187         movl    %r10d, %edi
188         callq   *%rax
189
190 .Larg1entryFail:
191         RESTORE_REGISTERS
192         retq
193
194 .Larg1entryEnd:
195         .size __xray_ArgLoggerEntry, .Larg1entryEnd-__xray_ArgLoggerEntry
196         .cfi_endproc
197
198 //===----------------------------------------------------------------------===//
199
200         .global __xray_CustomEvent
201         .align 16, 0x90
202         .type __xray_CustomEvent,@function
203 __xray_CustomEvent:
204   .cfi_startproc
205         subq $16, %rsp
206         .cfi_def_cfa_offset 24
207         movq %rbp, 8(%rsp)
208         movq %rax, 0(%rsp)
209
210         // We take two arguments to this trampoline, which should be in rdi     and rsi
211         // already. We also make sure that we stash %rax because we use that register
212         // to call the logging handler.
213         movq _ZN6__xray22XRayPatchedCustomEventE(%rip), %rax
214         testq %rax,%rax
215         je .LcustomEventCleanup
216
217         // At this point we know that rcx and rdx already has the data, so we just
218         // call the logging handler.
219   callq *%rax
220
221 .LcustomEventCleanup:
222         movq 0(%rsp), %rax
223         movq 8(%rsp), %rbp
224         addq $16, %rsp
225         .cfi_def_cfa_offset 8
226         retq
227
228 .Ltmp8:
229         .size __xray_CustomEvent, .Ltmp8-__xray_CustomEvent
230         .cfi_endproc
231
232 NO_EXEC_STACK_DIRECTIVE