aboutsummaryrefslogtreecommitdiffstats
path: root/continue-ia64.S
blob: ba61e38ef24ac70a59a7f4229ecc266245c0bf07 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
/* "continue-ia64.S" continuation support for ia64.
 * Copyright (C) 2006 Free Software Foundation, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 */

/* Author: Richard E. Harke */

/*
struct Continuation {jump_buf jmpbuf;
		     long thrwval;
		     long length;
		     STACKITEM *stkbse;
#ifdef __ia64__
                     long *bspbse;
                     long bsplength;
                     long rnat;
#endif
		     CONTINUATION_OTHER other;
		     struct Continuation *parent;
		   };
*/
/* Define offsets for elements of a Continuation structure */
#include "contoffset-ia64.S"


	.global	must_malloc
	.text
	.align	32
	.global	make_root_continuation
	.proc	make_root_continuation
make_root_continuation:
	.prologue
	.save	ar.pfs,r33
	alloc	r33 = ar.pfs,1,3,2,0
	.save	rp,r34
	mov	r34 = b0
	.body
	addl	r14 = @ltoffx(s_call_cc), r1
	mov	out0 = cont_size
	mov	loc2 = gp
	;;
	ld8.mov r14 = [r14], s_call_cc
	;;
	adds	out1 = 18, r14
	;;
	br.call.sptk.many	b0=must_malloc
	;;
	mov	gp = r35
	cmp.eq	p6,p0 = r8,r0
	adds	r14 = stkbse_off,r8
	adds	r15 = bspbse_off,r8
  (p6)  br.cond.dpnt	mrcexit
	;;
	flushrs
	st8	[r14] = r12
	;;
	mov	r31 = ar.bsp
	;;
	adds	r14 = length_off,r8
	st8	[r15] = r31
	adds	r16 = bsplength_off,r8
	;;
	st8	[r14] = r0
	st8	[r16] = r0
	adds	r15 = parent_off,r8
	;;
	st8	[r15] = r8
mrcexit:
	mov	ar.pfs = r33
	mov	b0 = r34
	;;
	br.ret.sptk.many	b0
	.endp	make_root_continuation

	/*
	register usage
	r32 - r39 used in modulo loop (requires multiple of 8)
	r40	save r32 from input
	r41	save return - b0
	r42	ar.pfs
	r43	save gp (r1)
	r44	ar.bsp
	r45	out0
	r46	out1
	*/
	.global make_continuation
	.proc make_continuation
make_continuation:
	.prologue
	.save ar.pfs, r42
	alloc	r42 = ar.pfs, 1,12, 2, 8
	mov	r43 = r1
	.save rp, r41
	mov	r41 = b0
	mov	r40 = r32
	;;
	.body
	adds	r14 = bspbse_off,r40
	adds	r17 = stkbse_off,r40
	;;
	mov	r44 = ar.bsp
	ld8	r15 = [r14]	// bspbse from parent
	ld8	r18 = [r17]	// stkbse from parent
	;;
	sub	r16 = r44,r15	// length of bsp to save
	sub	r19 = r18,r12	// length of stack to save
	addl	r15 = @ltoffx(s_call_cc), r1
	;;
	add	r45 = r16,r19	// bsp len plus stack len
	ld8.mov r14 = [r15], s_call_cc
	;;
	adds	r14 = 18, r14
	adds	r45 = cont_size, r45	// add in length of continuation struct
	;;
	mov	r46 = r14
	br.call.sptk.many	b0 = must_malloc
	mov	r1 = r43
	cmp.eq	p6, p7 = 0, r8
	(p6) br.cond.dptk .L5
	;;
.L1:
	flushrs
	adds	r14 = bspbse_off,r40
	adds	r17 = stkbse_off,r40
	;;
	mov	r31 = ar.rsc
	ld8	r15 = [r14]	// bsp in parent
	ld8	r18 = [r17]	// stack base in parent
	;;
	and	r30 = ~0x3,r31
	sub	r16 = r44,r15	// length of bsp to save
	sub	r19 = r18,r12	// length of stack to save
	;;
	mov	ar.rsc = r30	// set enforced idle
	shr	r16 = r16,3	// number of longs not bytes
	adds	r21 = length_off,r8
	adds	r22 = bsplength_off,r8
	shr	r19 = r19,3	// number of longs not bytes
	;;
	mov	r30 = ar.rnat
	add	r20 = r16,r19	// total length to save
	st8	[r22] = r16	// store the bsp length
	adds	r14 = bspbse_off,r8
	adds	r17 = stkbse_off,r8
	;;
	st8	[r14] = r44	// save current bsp
	st8	[r17] = r18	// stkbse same as parent stkbse
	adds	r22 = parent_off,r8
	st8	[r21] = r20	// store the length
	;;
	adds	r21 = rnat_off,r8
	st8	[r22] = r40	// store parent continuation
	mov	r29 = ar.lc	// need to preserve ar.lc
	mov	r28 = pr	// need to preserve pr.rot
	adds	r16 = -1,r16
	;;
	st8	[r21] = r30	// store rnat's
	mov	ar.lc = r16
	mov	ar.ec = 3
	mov	pr.rot = 0x10000
	adds	r27 = cont_size,r8
	adds	r19 = -1,r19
	;;
.L6:
  (p16)	ld8	r32 = [r15],8
  (p18)	st8	[r27] = r34,8
	br.ctop.sptk.few	.L6
	;;
	mov	r26 = r12
	clrrrb
	;;
	mov	ar.ec = 3
	mov	pr.rot = 0x10000
	mov	ar.lc = r19
	;;
.L7:
  (p16)	ld8	r32 = [r26],8
  (p18)	st8	[r27] = r34,8
	br.ctop.sptk.few	.L7
	;;
	mov	ar.lc = r29	// restore ar.lc
	mov	pr = r28,0x1003e	// restore pr
	mov	ar.rsc = r31	// restore ar.rsc
	;;
.L5:
	mov ar.pfs = r42
	mov b0 = r41
	br.ret.sptk.many b0
	.endp make_continuation


	.global	thrown_value
	.global	longjmp
	.global dynthrow
	.proc dynthrow
dynthrow:
	.prologue
	.save ar.pfs, r42
	alloc	r42 = ar.pfs, 1,12, 2, 8
	mov	r43 = r1
	.save rp, r44
	mov	r44 = b0
	ld8	r40 = [r32],8
	mov	r31 = ar.rsc
	movl	r2 = ~0x3fff0003
	;;
.L3:
	flushrs
	adds	r14 = bspbse_off,r40
	adds	r17 = stkbse_off,r40
	and	r30 = r2,r31
	;;
	ld8	r41 = [r32]
	ld8	r15 = [r14]	// bsp
	ld8	r18 = [r17]	// stack base
	mov	ar.rsc = r30	// set enforced idle
	;;
.L2:
	loadrs
	adds	r21 = length_off,r40
	adds	r22 = bsplength_off,r40
	;;
	mov	ar.bspstore = r15
	ld8	r16 = [r21]	// get total length (number of longs)
	ld8	r17 = [r22]	// get bsp length (number of longs)
	;;
	sub	r20 = r16,r17	// compute stack length
	shl	r25 = r17,3
	;;
	mov	r29 = ar.lc	// need to preserve ar.lc
	mov	r28 = pr	// need to preserve pr.rot
	sub	r15 = r15,r25	// adjust bsp beginning
	shl	r14 = r20,3
	adds	r17 = -1,r17
	adds	r21 = rnat_off,r40
	;;
	sub	r18 = r18,r14	// adjust stack to lowest
	mov	ar.lc = r17
	mov	ar.ec = 3
	mov	pr.rot = 0x10000
	adds	r27 = cont_size,r40
	adds	r20 = -1,r20
	;;
.L8:
  (p16)	ld8	r32 = [r27],8
  (p18)	st8	[r15] = r34,8
	br.ctop.sptk.few	.L8
	;;
	ld8	r14 = [r21]	// get the rnat's
	clrrrb
	;;
	mov	ar.ec = 3
	mov	pr.rot = 0x10000
	mov	ar.lc = r20
	;;
.L9:
  (p16)	ld8	r32 = [r27],8
  (p18)	st8	[r18] = r34,8
	br.ctop.sptk.few	.L9
	;;
	mov	ar.rnat = r14
	mov	ar.lc = r29	// restore ar.lc
	mov	pr = r28,0x1003e	// restore pr
	addl	r26 = @gprel(thrown_value),gp
	;;
	mov	ar.rsc = r31	// restore ar.rsc
	st8	[r26] = r41
	mov	r45 = r40
	mov	r46 = 1
	;;
	br.call.sptk.many	b0 = longjmp
// the following should not be executed
	mov	r1 = r43
	mov	ar.pfs = r42
	mov	b0 = r44
	br.ret.sptk.many b0
	.endp	dynthrow

	.global mark_locations
	.global	mark_regs_ia64
	.proc	mark_regs_ia64
mark_regs_ia64:
	.prologue
	.save	ar.pfs, r35
	alloc	r35 = ar.pfs, 1, 4, 2, 0
	.save	rp, r33
	mov	r33 = b0
	mov	r36 = r1
	mov	r34 = r12
	adds	r17 = stkbse_off, r32
	;;
	adds	r12 = -32, r12
	ld8	r19 = [r17]
	;;
	adds	r18 = 16,r12
        ;;
	sub	r38 = r19, r18
	;;
	st8	[r18] = r4, 8
	shr	r38 = r38, 3
	;;
	st8	[r18] = r5, 8
	;;
	st8	[r18] = r6, 8
	;;
	st8	[r18] = r7
	mov	r37 = r12
	br.call.sptk.many	b0 = mark_locations
	flushrs
	mov	r1 = r36
	adds	r17 = bspbse_off, r32
	;;
	mov	r20 = ar.bsp
	;;
	ld8	r37 = [r17]
	;;
	sub	r38 = r20, r37
	;;
	shr	r38 = r38, 3
	br.call.sptk.many	b0 = mark_locations
	mov	r1 = r36
	mov	r12 = r34
	mov	ar.pfs = r35
	mov	b0 = r33
	br.ret.sptk.many	b0
	.endp	mark_regs_ia64