1;; Copyright (C) 2013 Google Inc. All rights reserved.
2;;
3;; Redistribution and use in source and binary forms, with or without
4;; modification, are permitted provided that the following conditions are
5;; met:
6;;
7;;     * Redistributions of source code must retain the above copyright
8;; notice, this list of conditions and the following disclaimer.
9;;     * Redistributions in binary form must reproduce the above
10;; copyright notice, this list of conditions and the following disclaimer
11;; in the documentation and/or other materials provided with the
12;; distribution.
13;;     * Neither the name of Google Inc. nor the names of its
14;; contributors may be used to endorse or promote products derived from
15;; this software without specific prior written permission.
16;;
17;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28;;
29
30%ifndef X64POSIX
31%define X64POSIX 0
32%endif
33
34%ifndef X64WIN
35%define X64WIN 0
36%endif
37
38%ifndef IA32
39%define IA32 0
40%endif
41
42%ifndef ARM
43%define ARM 0
44%endif
45
46;; Prefix symbols by '_' if PREFIX is defined.
47%ifdef PREFIX
48%define mangle(x) _ %+ x
49%else
50%define mangle(x) x
51%endif
52
53
54; PRIVATE makes a symbol private.
55%ifidn   __OUTPUT_FORMAT__,elf32
56  %define PRIVATE :hidden
57%elifidn __OUTPUT_FORMAT__,elf64
58  %define PRIVATE :hidden
59%elifidn __OUTPUT_FORMAT__,elfx32
60  %define PRIVATE :hidden
61%elif X64WIN
62  %define PRIVATE
63%else
64  %define PRIVATE :private_extern
65%endif
66
67;; typedef void (*PushAllRegistersCallback)(SafePointBarrier*, ThreadState*, intptr_t*);
68;; extern "C" void pushAllRegisters(SafePointBarrier*, ThreadState*, PushAllRegistersCallback)
69
70        global mangle(pushAllRegisters) PRIVATE
71
72%if X64POSIX
73
74mangle(pushAllRegisters):
75        ;; Push all callee-saves registers to get them
76        ;; on the stack for conservative stack scanning.
77        ;; We maintain 16-byte alignment at calls (required on Mac).
78        ;; There is an 8-byte return address on the stack and we push
79        ;; 56 bytes which maintains 16-byte stack alignment
80        ;; at the call.
81        push 0
82        push rbx
83        push rbp
84        push r12
85        push r13
86        push r14
87        push r15
88        ;; Pass the two first arguments unchanged (rdi, rsi)
89        ;; and the stack pointer after pushing callee-saved
90        ;; registers to the callback.
91        mov r8, rdx
92        mov rdx, rsp
93        call r8
94        ;; Pop the callee-saved registers. None of them were
95        ;; modified so no restoring is needed.
96        add rsp, 56
97        ret
98
99%elif X64WIN
100
101mangle(pushAllRegisters):
102        ;; Push all callee-saves registers to get them
103        ;; on the stack for conservative stack scanning.
104        push rsi
105        push rdi
106        push rbx
107        push rbp
108        push r12
109        push r13
110        push r14
111        push r15
112        ;; Pass the two first arguments unchanged (rcx, rdx)
113        ;; and the stack pointer after pushing callee-saved
114        ;; registers to the callback.
115        mov r9, r8
116        mov r8, rsp
117        call r9
118        ;; Pop the callee-saved registers. None of them were
119        ;; modified so no restoring is needed.
120        add rsp, 64
121        ret
122
123%elif IA32
124
125mangle(pushAllRegisters):
126        ;; Push all callee-saves registers to get them
127        ;; on the stack for conservative stack scanning.
128        ;; We maintain 16-byte alignment at calls (required on
129        ;; Mac). There is a 4-byte return address on the stack
130        ;; and we push 28 bytes which maintains 16-byte alignment
131        ;; at the call.
132        push ebx
133        push ebp
134        push esi
135        push edi
136        ;; Pass the two first arguments unchanged and the
137        ;; stack pointer after pushing callee-save registers
138        ;; to the callback.
139        mov ecx, [esp + 28]
140        push esp
141        push dword [esp + 28]
142        push dword [esp + 28]
143        call ecx
144        ;; Pop arguments and the callee-saved registers.
145        ;; None of the callee-saved registers were modified
146        ;; so we do not need to restore them.
147        add esp, 28
148        ret
149
150
151%elif ARM
152%error "Yasm does not support arm. Use SaveRegisters_arm.S on arm."
153%else
154%error "Unsupported platform."
155%endif
156