Skip to content

Commit 840c99a

Browse files
committed
Port to ARMv8 A64
1 parent 7ab1f6a commit 840c99a

2 files changed

Lines changed: 113 additions & 0 deletions

File tree

context/switch-arm64.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/* This file is part of the Diamond cothread library.
2+
*
3+
* Copyright (C) 2010-2012 Michael Abbott, Diamond Light Source Ltd.
4+
*
5+
* The Diamond cothread library is free software; you can redistribute it
6+
* and/or modify it under the terms of the GNU General Public License as
7+
* published by the Free Software Foundation; either version 2 of the License,
8+
* or (at your option) any later version.
9+
*
10+
* The Diamond cothread library is distributed in the hope that it will be
11+
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13+
* Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License along
16+
* with this program; if not, write to the Free Software Foundation, Inc., 51
17+
* Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
*
19+
* Contact:
20+
* Dr. Michael Abbott,
21+
* Diamond Light Source Ltd,
22+
* Diamond House,
23+
* Chilton,
24+
* Didcot,
25+
* Oxfordshire,
26+
* OX11 0DE
27+
* michael.abbott@diamond.ac.uk
28+
*/
29+
30+
// Coroutine frame switching for ARMv8 64 bits
31+
32+
#ifdef __ARM_NEON
33+
#define IF_NEON(code) code
34+
#else
35+
#define IF_NEON(code)
36+
#endif
37+
38+
__asm__(
39+
" .text\n"
40+
41+
// void * switch_frame(frame_t *old_frame, frame_t new_frame, void *arg)
42+
// Arguments on entry:
43+
// x0 address of frame to be saved
44+
// x1 frame to be loaded
45+
// x2 Context argument to pass through
46+
47+
FNAME(switch_frame)
48+
" stp x19, x20, [sp, #-16]!\n"
49+
" stp x21, x22, [sp, #-16]!\n"
50+
" stp x23, x24, [sp, #-16]!\n"
51+
" stp x25, x26, [sp, #-16]!\n"
52+
" stp x27, x28, [sp, #-16]!\n"
53+
" stp fp, lr, [sp, #-16]!\n"
54+
IF_NEON(
55+
" stp d8, d9, [sp, #-16]!\n"
56+
" stp d10, d11, [sp, #-16]!\n"
57+
" stp d12, d13, [sp, #-16]!\n"
58+
" stp d14, d15, [sp, #-16]!\n"
59+
)
60+
" mov ip0, sp\n"
61+
" str ip0, [x0]\n"
62+
" mov sp, x1\n"
63+
" mov x0, x2\n"
64+
IF_NEON(
65+
" ldp d14, d15, [sp], #16\n"
66+
" ldp d12, d13, [sp], #16\n"
67+
" ldp d10, d11, [sp], #16\n"
68+
" ldp d8, d9, [sp], #16\n"
69+
)
70+
" ldp fp, lr, [sp], #16\n"
71+
" ldp x27, x28, [sp], #16\n"
72+
" ldp x25, x26, [sp], #16\n"
73+
" ldp x23, x24, [sp], #16\n"
74+
" ldp x21, x22, [sp], #16\n"
75+
" ldp x19, x20, [sp], #16\n"
76+
" br lr\n"
77+
FSIZE(switch_frame)
78+
79+
80+
// frame_t create_frame(void *stack_base, frame_action_t action, void *context)
81+
// Arguments on entry:
82+
// x0 initial base of stack
83+
// x1 action routine
84+
// x2 context argument to action
85+
FNAME(create_frame)
86+
" stp x1, x2, [x0, #-16]!\n"
87+
" mov ip0, lr\n" // Save LR so can use same STP slot
88+
" ldr lr, =action_entry\n"
89+
" stp x19, x20, [x0, #-16]!\n"
90+
" stp x21, x22, [x0, #-16]!\n"
91+
" stp x23, x24, [x0, #-16]!\n"
92+
" stp x25, x26, [x0, #-16]!\n"
93+
" stp x27, x28, [x0, #-16]!\n"
94+
" stp fp, lr, [x0, #-16]!\n"
95+
IF_NEON(
96+
" stp d8, d9, [x0, #-16]!\n"
97+
" stp d10, d11, [x0, #-16]!\n"
98+
" stp d12, d13, [x0, #-16]!\n"
99+
" stp d14, d15, [x0, #-16]!\n"
100+
)
101+
" br ip0\n"
102+
103+
"action_entry:\n"
104+
// Receive control after first switch to new frame. Top of stack has
105+
// the saved context and routine to call, switch argument is in r0.
106+
" ldp x2, x3, [sp], #16\n" // x2 <- action routine, x3 <- context
107+
" mov x1, x3\n"
108+
" mov lr, #0\n" // Ensure no return from action
109+
" br x2\n"
110+
FSIZE(create_frame)
111+
);

context/switch.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
#include "switch-x86.c"
4545
#elif defined(__x86_64__)
4646
#include "switch-x86_64.c"
47+
#elif defined(__aarch64__) && defined(__unix__)
48+
#include "switch-arm64.c"
4749
#elif defined(__arm__) && defined(__unix__)
4850
#include "switch-arm.c"
4951
#elif defined(__ppc__) && defined(__APPLE__)

0 commit comments

Comments
 (0)