blob: 91889c93f9aec781daf5932e7faccb2bd7036506 [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
Damien Georgeb4b10fd2015-01-01 23:30:53 +000035// the offset of nlr_top within mp_state_ctx_t
36#define NLR_TOP_OFFSET (2 * 8)
37
Damien George5b7aa292015-01-08 16:24:44 +000038#if defined(__APPLE__) && defined(__MACH__)
39#define NLR_TOP (_mp_state_ctx + NLR_TOP_OFFSET)
40#else
Damien Georgeb4b10fd2015-01-01 23:30:53 +000041#define NLR_TOP (mp_state_ctx + NLR_TOP_OFFSET)
Damien George5b7aa292015-01-08 16:24:44 +000042#endif
Damien Georgeb4b10fd2015-01-01 23:30:53 +000043
Damience89a212013-10-15 22:25:17 +010044 .file "nlr.s"
45 .text
46
Damien George4b34c762014-04-03 23:51:16 +010047#if !defined(__CYGWIN__)
48
Damien George133b0832014-09-26 13:07:26 +000049/******************************************************************************/
50//
51// Functions for *nix and OSX.
52// OSX needs _ prefix for binding to C, and doesn't support some directives.
53//
54/******************************************************************************/
Antonin ENFRUN6caae0b2014-05-11 21:28:26 +020055
Damien George133b0832014-09-26 13:07:26 +000056/**************************************/
57// mp_uint_t nlr_push(rdi=nlr_buf_t *nlr)
58
xbe60682102014-03-21 02:05:39 -070059#if !(defined(__APPLE__) && defined(__MACH__))
Damience89a212013-10-15 22:25:17 +010060 .globl nlr_push
61 .type nlr_push, @function
62nlr_push:
Mikael Eiman5d02e2d2014-01-04 20:15:04 +010063#else
64 .globl _nlr_push
65_nlr_push:
66#endif
Damience89a212013-10-15 22:25:17 +010067 movq (%rsp), %rax # load return %rip
68 movq %rax, 16(%rdi) # store %rip into nlr_buf
69 movq %rbp, 24(%rdi) # store %rbp into nlr_buf
70 movq %rsp, 32(%rdi) # store %rsp into nlr_buf
71 movq %rbx, 40(%rdi) # store %rbx into nlr_buf
72 movq %r12, 48(%rdi) # store %r12 into nlr_buf
73 movq %r13, 56(%rdi) # store %r13 into nlr_buf
74 movq %r14, 64(%rdi) # store %r14 into nlr_buf
75 movq %r15, 72(%rdi) # store %r15 into nlr_buf
Damien Georgeb4b10fd2015-01-01 23:30:53 +000076 movq NLR_TOP(%rip), %rax # get last nlr_buf
Damience89a212013-10-15 22:25:17 +010077 movq %rax, (%rdi) # store it
Damien Georgeb4b10fd2015-01-01 23:30:53 +000078 movq %rdi, NLR_TOP(%rip) # stor new nlr_buf (to make linked list)
Damience89a212013-10-15 22:25:17 +010079 xorq %rax, %rax # return 0, normal return
80 ret # return
xbe60682102014-03-21 02:05:39 -070081#if !(defined(__APPLE__) && defined(__MACH__))
Mikael Eimanf53cdd92014-01-04 20:19:19 +010082 .size nlr_push, .-nlr_push
83#endif
Damience89a212013-10-15 22:25:17 +010084
Damien George133b0832014-09-26 13:07:26 +000085/**************************************/
86// void nlr_pop()
87
xbe60682102014-03-21 02:05:39 -070088#if !(defined(__APPLE__) && defined(__MACH__))
Damience89a212013-10-15 22:25:17 +010089 .globl nlr_pop
90 .type nlr_pop, @function
91nlr_pop:
Mikael Eiman5d02e2d2014-01-04 20:15:04 +010092#else
93 .globl _nlr_pop
94_nlr_pop:
95#endif
Damien Georgeb4b10fd2015-01-01 23:30:53 +000096 movq NLR_TOP(%rip), %rax # get nlr_top into %rax
Damience89a212013-10-15 22:25:17 +010097 movq (%rax), %rax # load prev nlr_buf
Damien Georgeb4b10fd2015-01-01 23:30:53 +000098 movq %rax, NLR_TOP(%rip) # store prev nlr_buf (to unlink list)
Damience89a212013-10-15 22:25:17 +010099 ret # return
xbe60682102014-03-21 02:05:39 -0700100#if !(defined(__APPLE__) && defined(__MACH__))
Mikael Eimanf53cdd92014-01-04 20:19:19 +0100101 .size nlr_pop, .-nlr_pop
102#endif
Damience89a212013-10-15 22:25:17 +0100103
Damien George133b0832014-09-26 13:07:26 +0000104/**************************************/
105// void nlr_jump(rdi=mp_uint_t val)
106
xbe60682102014-03-21 02:05:39 -0700107#if !(defined(__APPLE__) && defined(__MACH__))
Damience89a212013-10-15 22:25:17 +0100108 .globl nlr_jump
109 .type nlr_jump, @function
110nlr_jump:
Mikael Eiman5d02e2d2014-01-04 20:15:04 +0100111#else
112 .globl _nlr_jump
113 _nlr_jump:
114#endif
Damience89a212013-10-15 22:25:17 +0100115 movq %rdi, %rax # put return value in %rax
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000116 movq NLR_TOP(%rip), %rdi # get nlr_top into %rdi
Damien George26cf55a2014-04-08 14:08:14 +0000117 test %rdi, %rdi # check for nlr_top being NULL
118 je .fail # fail if nlr_top is NULL
Damience89a212013-10-15 22:25:17 +0100119 movq %rax, 8(%rdi) # store return value
120 movq (%rdi), %rax # load prev nlr_buf
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000121 movq %rax, NLR_TOP(%rip) # store prev nlr_buf (to unlink list)
Damience89a212013-10-15 22:25:17 +0100122 movq 72(%rdi), %r15 # load saved %r15
123 movq 64(%rdi), %r14 # load saved %r14
124 movq 56(%rdi), %r13 # load saved %r13
125 movq 48(%rdi), %r12 # load saved %r12
126 movq 40(%rdi), %rbx # load saved %rbx
127 movq 32(%rdi), %rsp # load saved %rsp
128 movq 24(%rdi), %rbp # load saved %rbp
129 movq 16(%rdi), %rax # load saved %rip
130 movq %rax, (%rsp) # store saved %rip to stack
131 xorq %rax, %rax # clear return register
132 inc %al # increase to make 1, non-local return
133 ret # return
Damien George26cf55a2014-04-08 14:08:14 +0000134.fail:
135 movq %rax, %rdi # put argument back in first-arg register
xbe60682102014-03-21 02:05:39 -0700136#if !(defined(__APPLE__) && defined(__MACH__))
Damien George133b0832014-09-26 13:07:26 +0000137 je nlr_jump_fail # transfer control to nlr_jump_fail
Damience89a212013-10-15 22:25:17 +0100138 .size nlr_jump, .-nlr_jump
Damien George133b0832014-09-26 13:07:26 +0000139#else
140 je _nlr_jump_fail # transfer control to nlr_jump_fail
Mikael Eiman5d02e2d2014-01-04 20:15:04 +0100141#endif
Damience89a212013-10-15 22:25:17 +0100142
Damien George4b34c762014-04-03 23:51:16 +0100143#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
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000167 movq NLR_TOP(%rip), %rax # get last nlr_buf
Damien George4b34c762014-04-03 23:51:16 +0100168 movq %rax, (%rcx) # store it
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000169 movq %rcx, NLR_TOP(%rip) # stor new nlr_buf (to make linked list)
Damien George4b34c762014-04-03 23:51:16 +0100170 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:
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000178 movq NLR_TOP(%rip), %rax # get nlr_top into %rax
Damien George26cf55a2014-04-08 14:08:14 +0000179 movq (%rax), %rax # load prev nlr_buf
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000180 movq %rax, NLR_TOP(%rip) # store prev nlr_buf (to unlink list)
Damien George26cf55a2014-04-08 14:08:14 +0000181 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 Georgeb4b10fd2015-01-01 23:30:53 +0000189 movq NLR_TOP(%rip), %rcx # get nlr_top into %rcx
Damien George26cf55a2014-04-08 14:08:14 +0000190 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
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000194 movq %rax, NLR_TOP(%rip) # store prev nlr_buf (to unlink list)
Damien George4b34c762014-04-03 23:51:16 +0100195 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 George4b34c762014-04-03 23:51:16 +0100213#endif // !defined(__CYGWIN__)
214
Damien George133b0832014-09-26 13:07:26 +0000215#endif // defined(__x86_64__) && !MICROPY_NLR_SETJMP