1 /*
2  * This file is part of the MicroPython project, http://micropython.org/
3  *
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2019, Michael Neuling, IBM Corporation.
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 
29 #if MICROPY_NLR_POWERPC
30 
31 #undef nlr_push
32 
33 // Saving all ABI non-vol registers here
34 
nlr_push(nlr_buf_t * nlr)35 unsigned int nlr_push(nlr_buf_t *nlr) {
36 
37     __asm__ volatile (
38         "li     4, 0x4eed ; "  // Store canary
39         "std    4,  0x00(%0) ;"
40         "std    0,  0x08(%0) ;"
41         "std    1,  0x10(%0) ;"
42         "std    2,  0x18(%0) ;"
43         "std    14, 0x20(%0) ;"
44         "std    15, 0x28(%0) ;"
45         "std    16, 0x30(%0) ;"
46         "std    17, 0x38(%0) ;"
47         "std    18, 0x40(%0) ;"
48         "std    19, 0x48(%0) ;"
49         "std    20, 0x50(%0) ;"
50         "std    21, 0x58(%0) ;"
51         "std    22, 0x60(%0) ;"
52         "std    23, 0x68(%0) ;"
53         "std    24, 0x70(%0) ;"
54         "std    25, 0x78(%0) ;"
55         "std    26, 0x80(%0) ;"
56         "std    27, 0x88(%0) ;"
57         "std    28, 0x90(%0) ;"
58         "std    29, 0x98(%0) ;"
59         "std    30, 0xA0(%0) ;"
60         "std    31, 0xA8(%0) ;"
61 
62         "mfcr   4 ; "
63         "std    4, 0xB0(%0) ;"
64         "mflr   4 ;"
65         "std    4, 0xB8(%0) ;"
66         "li     4, nlr_push_tail@l ;"
67         "oris   4, 4, nlr_push_tail@h ;"
68         "mtctr  4 ;"
69         "mr    3, %1 ; "
70         "bctr  ;"
71         :
72         : "r" (&nlr->regs), "r" (nlr)
73         :
74         );
75 
76     return 0;
77 }
78 
nlr_jump(void * val)79 NORETURN void nlr_jump(void *val) {
80     MP_NLR_JUMP_HEAD(val, top)
81 
82     __asm__ volatile (
83         "ld    3, 0x0(%0) ;"
84         "cmpdi 3, 0x4eed ; " // Check canary
85         "bne   . ; "
86         "ld    0,  0x08(%0) ;"
87         "ld    1,  0x10(%0) ;"
88         "ld    2,  0x18(%0) ;"
89         "ld    14, 0x20(%0) ;"
90         "ld    15, 0x28(%0) ;"
91         "ld    16, 0x30(%0) ;"
92         "ld    17, 0x38(%0) ;"
93         "ld    18, 0x40(%0) ;"
94         "ld    19, 0x48(%0) ;"
95         "ld    20, 0x50(%0) ;"
96         "ld    21, 0x58(%0) ;"
97         "ld    22, 0x60(%0) ;"
98         "ld    23, 0x68(%0) ;"
99         "ld    24, 0x70(%0) ;"
100         "ld    25, 0x78(%0) ;"
101         "ld    26, 0x80(%0) ;"
102         "ld    27, 0x88(%0) ;"
103         "ld    28, 0x90(%0) ;"
104         "ld    29, 0x98(%0) ;"
105         "ld    30, 0xA0(%0) ;"
106         "ld    31, 0xA8(%0) ;"
107         "ld    3,  0xB0(%0) ;"
108         "mtcr  3 ;"
109         "ld    3, 0xB8(%0) ;"
110         "mtlr  3 ; "
111         "li    3, 1;"
112         "blr ;"
113         :
114         : "r" (&top->regs)
115         :
116         );
117 
118     MP_UNREACHABLE;
119 }
120 
121 #endif // MICROPY_NLR_POWERPC
122