blob: d00102050bbc02ff0c3e547915ff4e6215564eb0 [file] [log] [blame]
Damien George04b91472014-05-03 23:27:38 +01001/*
2 * This file is part of the Micro Python project, http://micropython.org/
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (c) 2013, 2014 Damien P. George
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
Paul Sokolovskyb1ce37d2014-04-30 04:19:20 +030027#if defined(__x86_64__) && !MICROPY_NLR_SETJMP
Damien George133b0832014-09-26 13:07:26 +000028
29// We only need the functions here if we are on x86-64, and we are not
30// using setjmp/longjmp.
31//
32// For reference, x86-64 callee save regs are:
33// rbx, rbp, rsp, r12, r13, r14, r15
Damience89a212013-10-15 22:25:17 +010034
35 .file "nlr.s"
36 .text
37
Damien George4b34c762014-04-03 23:51:16 +010038#if !defined(__CYGWIN__)
39
Damien George133b0832014-09-26 13:07:26 +000040/******************************************************************************/
41//
42// Functions for *nix and OSX.
43// OSX needs _ prefix for binding to C, and doesn't support some directives.
44//
45/******************************************************************************/
Antonin ENFRUN6caae0b2014-05-11 21:28:26 +020046
Damien George133b0832014-09-26 13:07:26 +000047/**************************************/
48// mp_uint_t nlr_push(rdi=nlr_buf_t *nlr)
49
xbe60682102014-03-21 02:05:39 -070050#if !(defined(__APPLE__) && defined(__MACH__))
Damience89a212013-10-15 22:25:17 +010051 .globl nlr_push
52 .type nlr_push, @function
53nlr_push:
Mikael Eiman5d02e2d2014-01-04 20:15:04 +010054#else
55 .globl _nlr_push
56_nlr_push:
57#endif
Damience89a212013-10-15 22:25:17 +010058 movq (%rsp), %rax # load return %rip
59 movq %rax, 16(%rdi) # store %rip into nlr_buf
60 movq %rbp, 24(%rdi) # store %rbp into nlr_buf
61 movq %rsp, 32(%rdi) # store %rsp into nlr_buf
62 movq %rbx, 40(%rdi) # store %rbx into nlr_buf
63 movq %r12, 48(%rdi) # store %r12 into nlr_buf
64 movq %r13, 56(%rdi) # store %r13 into nlr_buf
65 movq %r14, 64(%rdi) # store %r14 into nlr_buf
66 movq %r15, 72(%rdi) # store %r15 into nlr_buf
67 movq nlr_top(%rip), %rax # get last nlr_buf
68 movq %rax, (%rdi) # store it
69 movq %rdi, nlr_top(%rip) # stor new nlr_buf (to make linked list)
70 xorq %rax, %rax # return 0, normal return
71 ret # return
xbe60682102014-03-21 02:05:39 -070072#if !(defined(__APPLE__) && defined(__MACH__))
Mikael Eimanf53cdd92014-01-04 20:19:19 +010073 .size nlr_push, .-nlr_push
74#endif
Damience89a212013-10-15 22:25:17 +010075
Damien George133b0832014-09-26 13:07:26 +000076/**************************************/
77// void nlr_pop()
78
xbe60682102014-03-21 02:05:39 -070079#if !(defined(__APPLE__) && defined(__MACH__))
Damience89a212013-10-15 22:25:17 +010080 .globl nlr_pop
81 .type nlr_pop, @function
82nlr_pop:
Mikael Eiman5d02e2d2014-01-04 20:15:04 +010083#else
84 .globl _nlr_pop
85_nlr_pop:
86#endif
Damience89a212013-10-15 22:25:17 +010087 movq nlr_top(%rip), %rax # get nlr_top into %rax
88 movq (%rax), %rax # load prev nlr_buf
89 movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
90 ret # return
xbe60682102014-03-21 02:05:39 -070091#if !(defined(__APPLE__) && defined(__MACH__))
Mikael Eimanf53cdd92014-01-04 20:19:19 +010092 .size nlr_pop, .-nlr_pop
93#endif
Damience89a212013-10-15 22:25:17 +010094
Damien George133b0832014-09-26 13:07:26 +000095/**************************************/
96// void nlr_jump(rdi=mp_uint_t val)
97
xbe60682102014-03-21 02:05:39 -070098#if !(defined(__APPLE__) && defined(__MACH__))
Damience89a212013-10-15 22:25:17 +010099 .globl nlr_jump
100 .type nlr_jump, @function
101nlr_jump:
Mikael Eiman5d02e2d2014-01-04 20:15:04 +0100102#else
103 .globl _nlr_jump
104 _nlr_jump:
105#endif
Damience89a212013-10-15 22:25:17 +0100106 movq %rdi, %rax # put return value in %rax
107 movq nlr_top(%rip), %rdi # get nlr_top into %rdi
Damien George26cf55a2014-04-08 14:08:14 +0000108 test %rdi, %rdi # check for nlr_top being NULL
109 je .fail # fail if nlr_top is NULL
Damience89a212013-10-15 22:25:17 +0100110 movq %rax, 8(%rdi) # store return value
111 movq (%rdi), %rax # load prev nlr_buf
112 movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
113 movq 72(%rdi), %r15 # load saved %r15
114 movq 64(%rdi), %r14 # load saved %r14
115 movq 56(%rdi), %r13 # load saved %r13
116 movq 48(%rdi), %r12 # load saved %r12
117 movq 40(%rdi), %rbx # load saved %rbx
118 movq 32(%rdi), %rsp # load saved %rsp
119 movq 24(%rdi), %rbp # load saved %rbp
120 movq 16(%rdi), %rax # load saved %rip
121 movq %rax, (%rsp) # store saved %rip to stack
122 xorq %rax, %rax # clear return register
123 inc %al # increase to make 1, non-local return
124 ret # return
Damien George26cf55a2014-04-08 14:08:14 +0000125.fail:
126 movq %rax, %rdi # put argument back in first-arg register
xbe60682102014-03-21 02:05:39 -0700127#if !(defined(__APPLE__) && defined(__MACH__))
Damien George133b0832014-09-26 13:07:26 +0000128 je nlr_jump_fail # transfer control to nlr_jump_fail
Damience89a212013-10-15 22:25:17 +0100129 .size nlr_jump, .-nlr_jump
Damien George133b0832014-09-26 13:07:26 +0000130#else
131 je _nlr_jump_fail # transfer control to nlr_jump_fail
Mikael Eiman5d02e2d2014-01-04 20:15:04 +0100132#endif
Damience89a212013-10-15 22:25:17 +0100133
Damien George133b0832014-09-26 13:07:26 +0000134/**************************************/
135// local variable nlr_top
136
xbe60682102014-03-21 02:05:39 -0700137#if !(defined(__APPLE__) && defined(__MACH__))
Damien George133b0832014-09-26 13:07:26 +0000138 .bss
Damience89a212013-10-15 22:25:17 +0100139 .local nlr_top
Mikael Eiman5d02e2d2014-01-04 20:15:04 +0100140#endif
Damience89a212013-10-15 22:25:17 +0100141 .comm nlr_top,8,8
Damien George4b34c762014-04-03 23:51:16 +0100142
143#else // !defined(__CYGWIN__)
144
Damien George133b0832014-09-26 13:07:26 +0000145/******************************************************************************/
146//
147// Functions for Cygwin
148//
149/******************************************************************************/
150
151/**************************************/
152// mp_uint_t nlr_push(rcx=nlr_buf_t *nlr)
153
Damien George4b34c762014-04-03 23:51:16 +0100154 .globl nlr_push
155nlr_push:
156 movq (%rsp), %rax # load return %rip
157 movq %rax, 16(%rcx) # store %rip into nlr_buf
158 movq %rbp, 24(%rcx) # store %rbp into nlr_buf
159 movq %rsp, 32(%rcx) # store %rsp into nlr_buf
160 movq %rbx, 40(%rcx) # store %rbx into nlr_buf
161 movq %r12, 48(%rcx) # store %r12 into nlr_buf
162 movq %r13, 56(%rcx) # store %r13 into nlr_buf
163 movq %r14, 64(%rcx) # store %r14 into nlr_buf
164 movq %r15, 72(%rcx) # store %r15 into
165 movq %rdi, 80(%rcx) # store %rdr into
166 movq %rsi, 88(%rcx) # store %rsi into
167 movq nlr_top(%rip), %rax # get last nlr_buf
168 movq %rax, (%rcx) # store it
169 movq %rcx, nlr_top(%rip) # stor new nlr_buf (to make linked list)
170 xorq %rax, %rax # return 0, normal return
171 ret # return
172
Damien George133b0832014-09-26 13:07:26 +0000173/**************************************/
174// void nlr_pop()
175
Damien George26cf55a2014-04-08 14:08:14 +0000176 .globl nlr_pop
177nlr_pop:
178 movq nlr_top(%rip), %rax # get nlr_top into %rax
179 movq (%rax), %rax # load prev nlr_buf
180 movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
181 ret # return
Damien George4b34c762014-04-03 23:51:16 +0100182
Damien George133b0832014-09-26 13:07:26 +0000183/**************************************/
184// void nlr_jump(rcx=mp_uint_t val)
185
Damien George4b34c762014-04-03 23:51:16 +0100186 .globl nlr_jump
187nlr_jump:
188 movq %rcx, %rax # put return value in %rax
Damien George26cf55a2014-04-08 14:08:14 +0000189 movq nlr_top(%rip), %rcx # get nlr_top into %rcx
190 test %rcx, %rcx # check for nlr_top being NULL
191 je .fail # fail if nlr_top is NULL
Damien George4b34c762014-04-03 23:51:16 +0100192 movq %rax, 8(%rcx) # store return value
193 movq (%rcx), %rax # load prev nlr_buf
194 movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
195 movq 72(%rcx), %r15 # load saved %r15
196 movq 64(%rcx), %r14 # load saved %r14
197 movq 56(%rcx), %r13 # load saved %r13
198 movq 48(%rcx), %r12 # load saved %r12
199 movq 40(%rcx), %rbx # load saved %rbx
200 movq 32(%rcx), %rsp # load saved %rsp
201 movq 24(%rcx), %rbp # load saved %rbp
202 movq 16(%rcx), %rax # load saved %rip
203 movq 80(%rcx), %rdi # store %rdr into
204 movq 88(%rcx), %rsi # store %rsi into
205 movq %rax, (%rsp) # store saved %rip to stack
206 xorq %rax, %rax # clear return register
207 inc %al # increase to make 1, non-local return
208 ret # return
Damien George26cf55a2014-04-08 14:08:14 +0000209.fail:
210 movq %rax, %rcx # put argument back in first-arg register
211 je nlr_jump_fail # transfer control to nlr_jump_fail
Damien George4b34c762014-04-03 23:51:16 +0100212
Damien George133b0832014-09-26 13:07:26 +0000213/**************************************/
214// local variable nlr_top
215
Damien George26cf55a2014-04-08 14:08:14 +0000216 .bss
Damien George4b34c762014-04-03 23:51:16 +0100217 .comm nlr_top,8,8
218
Damien George4b34c762014-04-03 23:51:16 +0100219#endif // !defined(__CYGWIN__)
220
Damien George133b0832014-09-26 13:07:26 +0000221#endif // defined(__x86_64__) && !MICROPY_NLR_SETJMP