Skip to content

Commit 3218484

Browse files
committed
py/nlrx64: Convert from assembler to C file with inline asm.
1 parent a85755a commit 3218484

2 files changed

Lines changed: 129 additions & 262 deletions

File tree

py/nlrx64.S

Lines changed: 0 additions & 262 deletions
This file was deleted.

py/nlrx64.c

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2013-2017 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+
27+
#include "py/mpstate.h"
28+
#include "py/nlr.h"
29+
30+
#if !MICROPY_NLR_SETJMP && defined(__x86_64__)
31+
32+
#undef nlr_push
33+
34+
// x86-64 callee-save registers are:
35+
// rbx, rbp, rsp, r12, r13, r14, r15
36+
37+
#define NLR_OS_WINDOWS (defined(_WIN32) || defined(__CYGWIN__))
38+
39+
__attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr);
40+
41+
unsigned int nlr_push(nlr_buf_t *nlr) {
42+
(void)nlr;
43+
44+
#if NLR_OS_WINDOWS
45+
46+
__asm volatile (
47+
"movq (%rsp), %rax \n" // load return %rip
48+
"movq %rax, 16(%rcx) \n" // store %rip into nlr_buf
49+
"movq %rbp, 24(%rcx) \n" // store %rbp into nlr_buf
50+
"movq %rsp, 32(%rcx) \n" // store %rsp into nlr_buf
51+
"movq %rbx, 40(%rcx) \n" // store %rbx into nlr_buf
52+
"movq %r12, 48(%rcx) \n" // store %r12 into nlr_buf
53+
"movq %r13, 56(%rcx) \n" // store %r13 into nlr_buf
54+
"movq %r14, 64(%rcx) \n" // store %r14 into nlr_buf
55+
"movq %r15, 72(%rcx) \n" // store %r15 into nlr_buf
56+
"movq %rdi, 80(%rcx) \n" // store %rdr into nlr_buf
57+
"movq %rsi, 88(%rcx) \n" // store %rsi into nlr_buf
58+
"jmp nlr_push_tail \n" // do the rest in C
59+
);
60+
61+
#else
62+
63+
__asm volatile (
64+
"movq (%rsp), %rax \n" // load return %rip
65+
"movq %rax, 16(%rdi) \n" // store %rip into nlr_buf
66+
"movq %rbp, 24(%rdi) \n" // store %rbp into nlr_buf
67+
"movq %rsp, 32(%rdi) \n" // store %rsp into nlr_buf
68+
"movq %rbx, 40(%rdi) \n" // store %rbx into nlr_buf
69+
"movq %r12, 48(%rdi) \n" // store %r12 into nlr_buf
70+
"movq %r13, 56(%rdi) \n" // store %r13 into nlr_buf
71+
"movq %r14, 64(%rdi) \n" // store %r14 into nlr_buf
72+
"movq %r15, 72(%rdi) \n" // store %r15 into nlr_buf
73+
"jmp nlr_push_tail \n" // do the rest in C
74+
);
75+
76+
#endif
77+
78+
return 0; // needed to silence compiler warning
79+
}
80+
81+
__attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr) {
82+
nlr_buf_t **top = &MP_STATE_THREAD(nlr_top);
83+
nlr->prev = *top;
84+
*top = nlr;
85+
return 0; // normal return
86+
}
87+
88+
void nlr_pop(void) {
89+
nlr_buf_t **top = &MP_STATE_THREAD(nlr_top);
90+
*top = (*top)->prev;
91+
}
92+
93+
NORETURN void nlr_jump(void *val) {
94+
nlr_buf_t **top_ptr = &MP_STATE_THREAD(nlr_top);
95+
nlr_buf_t *top = *top_ptr;
96+
if (top == NULL) {
97+
nlr_jump_fail(val);
98+
}
99+
100+
top->ret_val = val;
101+
*top_ptr = top->prev;
102+
103+
__asm volatile (
104+
"movq %0, %%rcx \n" // %rcx points to nlr_buf
105+
#if NLR_OS_WINDOWS
106+
"movq 88(%%rcx), %%rsi \n" // load saved %rsi
107+
"movq 80(%%rcx), %%rdi \n" // load saved %rdr
108+
#endif
109+
"movq 72(%%rcx), %%r15 \n" // load saved %r15
110+
"movq 64(%%rcx), %%r14 \n" // load saved %r14
111+
"movq 56(%%rcx), %%r13 \n" // load saved %r13
112+
"movq 48(%%rcx), %%r12 \n" // load saved %r12
113+
"movq 40(%%rcx), %%rbx \n" // load saved %rbx
114+
"movq 32(%%rcx), %%rsp \n" // load saved %rsp
115+
"movq 24(%%rcx), %%rbp \n" // load saved %rbp
116+
"movq 16(%%rcx), %%rax \n" // load saved %rip
117+
"movq %%rax, (%%rsp) \n" // store saved %rip to stack
118+
"xorq %%rax, %%rax \n" // clear return register
119+
"inc %%al \n" // increase to make 1, non-local return
120+
"ret \n" // return
121+
: // output operands
122+
: "r"(top) // input operands
123+
: // clobbered registers
124+
);
125+
126+
for (;;); // needed to silence compiler warning
127+
}
128+
129+
#endif // !MICROPY_NLR_SETJMP && defined(__x86_64__)

0 commit comments

Comments
 (0)