1/*
2            Copyright Oliver Kowalke 2009.
3   Distributed under the Boost Software License, Version 1.0.
4      (See accompanying file LICENSE_1_0.txt or copy at
5          http://www.boost.org/LICENSE_1_0.txt)
6*/
7
8/*******************************************************
9 *                                                     *
10 *  -------------------------------------------------  *
11 *  |  0  |  4  |  8  |  12 |  16 |  20 |  24 |  28 |  *
12 *  -------------------------------------------------  *
13 *  |bchai|hiddn|   fpscr   |  PC |  CR | R14 | R15 |  *
14 *  -------------------------------------------------  *
15 *  -------------------------------------------------  *
16 *  |  32 |  36 |  40 |  44 |  48 |  52 |  56 |  60 |  *
17 *  -------------------------------------------------  *
18 *  | R16 | R17 | R18 | R19 | R20 | R21 | R22 | R23 |  *
19 *  -------------------------------------------------  *
20 *  -------------------------------------------------  *
21 *  |  64 |  68 |  72 |  76 |  80 |  84 |  88 |  92 |  *
22 *  -------------------------------------------------  *
23 *  | R24 | R25 | R26 | R27 | R28 | R29 | R30 | R31 |  *
24 *  -------------------------------------------------  *
25 *  -------------------------------------------------  *
26 *  |  96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 |  *
27 *  -------------------------------------------------  *
28 *  |    F14    |    F15    |    F16    |    F17    |  *
29 *  -------------------------------------------------  *
30 *  -------------------------------------------------  *
31 *  | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 |  *
32 *  -------------------------------------------------  *
33 *  |    F18    |    F19    |    F20    |    F21    |  *
34 *  -------------------------------------------------  *
35 *  -------------------------------------------------  *
36 *  | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 |  *
37 *  -------------------------------------------------  *
38 *  |    F22    |    F23    |    F24    |    F25    |  *
39 *  -------------------------------------------------  *
40 *  -------------------------------------------------  *
41 *  | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 |  *
42 *  -------------------------------------------------  *
43 *  |    F26    |    F27    |    F28    |    F29    |  *
44 *  -------------------------------------------------  *
45 *  ------------------------|------------              *
46 *  | 224 | 228 | 232 | 236 | 240 | 244 |              *
47 *  ------------------------|------------              *
48 *  |    F30    |    F31    |bchai|  LR |              *
49 *  ------------------------|------------              *
50 *                                                     *
51 *******************************************************/
52
53.file "jump_ppc32_sysv_elf_gas.S"
54.text
55.globl jump_fcontext
56.align 2
57.type jump_fcontext,@function
58jump_fcontext:
59    # Linux: jump_fcontext( hidden transfer_t * R3, R4, R5)
60    # Other: transfer_t R3:R4 = jump_fcontext( R3, R4)
61
62    mflr  %r0  # return address from LR
63    mffs  %f0  # FPSCR
64    mfcr  %r8  # condition register
65
66    stwu  %r1, -240(%r1)  # allocate stack space, R1 % 16 == 0
67    stw   %r0, 244(%r1)   # save LR in caller's frame
68
69#ifdef __linux__
70    stw   %r3, 4(%r1)   # hidden pointer
71#endif
72
73    stfd  %f0, 8(%r1)   # FPSCR
74    stw   %r0, 16(%r1)  # LR as PC
75    stw   %r8, 20(%r1)  # CR
76
77    # Save registers R14 to R31.
78    # Don't change R2, the thread-local storage pointer.
79    # Don't change R13, the small data pointer.
80    stw   %r14, 24(%r1)
81    stw   %r15, 28(%r1)
82    stw   %r16, 32(%r1)
83    stw   %r17, 36(%r1)
84    stw   %r18, 40(%r1)
85    stw   %r19, 44(%r1)
86    stw   %r20, 48(%r1)
87    stw   %r21, 52(%r1)
88    stw   %r22, 56(%r1)
89    stw   %r23, 60(%r1)
90    stw   %r24, 64(%r1)
91    stw   %r25, 68(%r1)
92    stw   %r26, 72(%r1)
93    stw   %r27, 76(%r1)
94    stw   %r28, 80(%r1)
95    stw   %r29, 84(%r1)
96    stw   %r30, 88(%r1)
97    stw   %r31, 92(%r1)
98
99    # Save registers F14 to F31 in slots with 8-byte alignment.
100    # 4-byte alignment may stall the pipeline of some processors.
101    # Less than 4 may cause alignment traps.
102    stfd  %f14, 96(%r1)
103    stfd  %f15, 104(%r1)
104    stfd  %f16, 112(%r1)
105    stfd  %f17, 120(%r1)
106    stfd  %f18, 128(%r1)
107    stfd  %f19, 136(%r1)
108    stfd  %f20, 144(%r1)
109    stfd  %f21, 152(%r1)
110    stfd  %f22, 160(%r1)
111    stfd  %f23, 168(%r1)
112    stfd  %f24, 176(%r1)
113    stfd  %f25, 184(%r1)
114    stfd  %f26, 192(%r1)
115    stfd  %f27, 200(%r1)
116    stfd  %f28, 208(%r1)
117    stfd  %f29, 216(%r1)
118    stfd  %f30, 224(%r1)
119    stfd  %f31, 232(%r1)
120
121    # store RSP (pointing to context-data) in R7/R6
122    # restore RSP (pointing to context-data) from R4/R3
123#ifdef __linux__
124    mr   %r7, %r1
125    mr   %r1, %r4
126    lwz  %r3, 4(%r1)   # hidden pointer
127#else
128    mr   %r6, %r1
129    mr   %r1, %r3
130#endif
131
132    lfd  %f0, 8(%r1)   # FPSCR
133    lwz  %r0, 16(%r1)  # PC
134    lwz  %r8, 20(%r1)  # CR
135
136    mtfsf  0xff, %f0   # restore FPSCR
137    mtctr  %r0         # load CTR with PC
138    mtcr   %r8         # restore CR
139
140    # restore R14 to R31
141    lwz  %r14, 24(%r1)
142    lwz  %r15, 28(%r1)
143    lwz  %r16, 32(%r1)
144    lwz  %r17, 36(%r1)
145    lwz  %r18, 40(%r1)
146    lwz  %r19, 44(%r1)
147    lwz  %r20, 48(%r1)
148    lwz  %r21, 52(%r1)
149    lwz  %r22, 56(%r1)
150    lwz  %r23, 60(%r1)
151    lwz  %r24, 64(%r1)
152    lwz  %r25, 68(%r1)
153    lwz  %r26, 72(%r1)
154    lwz  %r27, 76(%r1)
155    lwz  %r28, 80(%r1)
156    lwz  %r29, 84(%r1)
157    lwz  %r30, 88(%r1)
158    lwz  %r31, 92(%r1)
159
160    # restore F14 to F31
161    lfd  %f14, 96(%r1)
162    lfd  %f15, 104(%r1)
163    lfd  %f16, 112(%r1)
164    lfd  %f17, 120(%r1)
165    lfd  %f18, 128(%r1)
166    lfd  %f19, 136(%r1)
167    lfd  %f20, 144(%r1)
168    lfd  %f21, 152(%r1)
169    lfd  %f22, 160(%r1)
170    lfd  %f23, 168(%r1)
171    lfd  %f24, 176(%r1)
172    lfd  %f25, 184(%r1)
173    lfd  %f26, 192(%r1)
174    lfd  %f27, 200(%r1)
175    lfd  %f28, 208(%r1)
176    lfd  %f29, 216(%r1)
177    lfd  %f30, 224(%r1)
178    lfd  %f31, 232(%r1)
179
180    # restore LR from caller's frame
181    lwz   %r0, 244(%r1)
182    mtlr  %r0
183
184    # adjust stack
185    addi  %r1, %r1, 240
186
187    # return transfer_t
188#ifdef __linux__
189    stw  %r7, 0(%r3)
190    stw  %r5, 4(%r3)
191#else
192    mr   %r3, %r6
193    #    %r4, %r4
194#endif
195
196    # jump to context
197    bctr
198.size jump_fcontext, .-jump_fcontext
199
200/* Mark that we don't need executable stack.  */
201.section .note.GNU-stack,"",%progbits
202