Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / lwp / process.default.s
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10 #define IGNORE_STDS_H 1
11 #include <afs/param.h>
12
13 #if defined(__arm32__) || defined(__arm__)
14 #ifndef AFS_ARM_DARWIN_ENV
15 /* register definitions */
16 fp .req r11
17 ip .req r12
18 sp .req r13
19 lp .req r14
20 pc .req r15
21 #endif
22
23 /*
24 savecontext(f, area1, newsp)
25 int (*f)()#if defined(RIOS);
26 struct savearea *area1;
27 char *newsp;
28 */
29
30 /* Arguments appear as: f in r0, area1 in r1, newsp in r2 */
31
32 .text
33 .align 0
34 #ifndef AFS_ARM_DARWIN_ENV
35 .globl savecontext
36 .type savecontext, #function
37 savecontext:
38 #else
39 .globl _savecontext
40 _savecontext:
41 #endif
42 @ build the frame
43 mov ip, sp
44 stmfd sp!, {fp, ip, lr, pc}
45 sub fp, ip, #4
46 @ stack r0 - r10, current fp
47 stmfd sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, fp}
48 str sp, [r1, #0]
49 @ check if newsp is zero
50 movs r2, r2
51 movne sp, r2
52 @ call function ...
53 #ifdef AFS_ARM_DARWIN_ENV
54 bx r0
55 #else
56 mov pc, r0
57 #endif
58
59 /*
60 returnto(area2)
61 struct savearea *area2;
62 */
63
64 /* area2 is in r0. */
65
66 #ifndef AFS_ARM_DARWIN_ENV
67 .globl returnto
68 .type returnto, #function
69 returnto:
70 #else
71 .globl _returnto
72 _returnto:
73 #endif
74 @ restore r0-r10, fp
75 ldr r0, [r0, #0]
76 ldmfd r0, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, fp}
77 @ return from function call
78 ldmea fp, {fp, sp, pc}
79
80 #endif /* __arm32__ or __arm__ */
81
82 #if defined(RIOS)
83 /* I don't know if we have to save the TOC (R2) or not...
84 * Note that stack-frame is supposed to be aligned on
85 * a double-word boundary.
86 * For details about RIOS calling conventions
87 * see the Assembler manual and /usr/include/sys/asdef.s
88 */
89
90
91 /*
92 * savecontext(f, area1, newsp)
93 * int (*f)(); struct savearea *area1; char *newsp;
94 */
95 .set topstack, 0
96 .set cr0, 0
97 .set toc, 2
98 .set r0, 0
99 .set r1, 1
100 .set r2, 2
101 .set r3, 3
102 .set r4, 4
103 .set r5, 5
104 .set r6, 6
105 .set r7, 7
106 .set r12, 12
107 .set a_f, r3
108 .set a_area1, r4
109 .set a_newsp, r5
110
111 .set argarea, 32
112 .set linkarea, 24
113 .set nfprs, 18
114 .set ngprs, 20
115 .set szdsa, 8*nfprs+4*ngprs+linkarea+argarea
116
117 .csect .savecontext[PR]
118 .globl .savecontext[PR]
119
120 mflr r0 # save link register
121
122 /*
123 * save floating point registers. Interleave some other stuff for
124 * timing reasons. Set up conditions and registers for branches
125 * early, so that processor can prefetch instructions.
126 */
127 stfd 14, -144(1)
128 stfd 15, -136(1)
129
130 mfcr r12 # save CR
131
132 stfd 16, -128(1)
133 stfd 17, -120(1)
134
135 l 11, 0(a_f) # r11 <- *(a_f)
136
137 stfd 18, -112(1)
138 stfd 19, -104(1)
139
140 cmpi cr0, a_newsp, 0 # cr0 <- (a_newsp :: 0)
141
142 stfd 20, -96(1)
143 stfd 21, -88(1)
144 stfd 22, -80(1)
145
146 mtlr 11 # set up lr early so prefetch works
147
148 stfd 23, -72(1)
149 stfd 24, -64(1)
150 stfd 25, -56(1)
151
152 st r0, 8(r1) # save return addr
153
154 stfd 26, -48(1)
155 stfd 27, -40(1)
156 stfd 28, -32(1)
157
158 st 12, 4(r1) # save CR
159
160 stfd 29, -24(1)
161 stfd 30, -16(1)
162 stfd 31, -8(1)
163
164 /*
165 * save general-purpose registers
166 */
167 stm 12, -8*nfprs-4*ngprs(r1)# save the general-purpose regs
168 stu r1, -szdsa(r1) # dec SP and save back chain
169
170 l r7, PRE_Block.S(toc) # r7 <- &PRE_Block
171 cal r6, 1(r0) # r6 <- #1
172 stb r6, 0(r7) # r6 -> PRE_Block
173
174 st r1, topstack(a_area1) # save old SP
175
176 beq L1 # if (a_newsp == 0) goto L1
177
178 mr r1, r5 # r1 <- a_newsp -- load new SP
179
180 L1: brl # pc <- lr -- (*a_f)()
181
182 /*
183 * returnto(area2) This is a little jumbled, I tried to interleave
184 * memory accesses with simple instructions for speed, and I tried to
185 * set up the link register and condition register reasonably early
186 * so that processor instruction prefetching might help us out a little.
187 */
188 .set a_area2, r3
189
190 .csect .returnto[PR]
191 .globl .returnto[PR]
192
193 l r1, topstack(a_area2) # r1 <- a_area2->topstack
194 cal r1, szdsa(r1) # pop off frame
195 l r7, PRE_Block.S(toc) # r7 <- &PRE_Block
196
197 l 8, 8(1) # restore lr
198 mtlr 8 # do it early so prefetch works
199
200 lm 12, -8*nfprs-4*ngprs(r1)
201 cal r6, 0(r0) # r6 <- #0
202 mtcrf 0x38, 12 # put back cr
203 stb r6, 0(r7) # r6 -> PRE_Block
204
205 /*
206 * restore FPRs here!
207 */
208 lfd 14, -144(1)
209 lfd 15, -136(1)
210 lfd 16, -128(1)
211 lfd 17, -120(1)
212 lfd 18, -112(1)
213 lfd 19, -104(1)
214 lfd 20, -96(1)
215 lfd 21, -88(1)
216 lfd 22, -80(1)
217 lfd 23, -72(1)
218 lfd 24, -64(1)
219 lfd 25, -56(1)
220 lfd 26, -48(1)
221 lfd 27, -40(1)
222 lfd 28, -32(1)
223 lfd 29, -24(1)
224 lfd 30, -16(1)
225 lfd 31, -8(1)
226
227 brl # pc <- lr -- return
228
229 .toc
230
231 PRE_Block.S:
232 .tc PRE_Block[tc], PRE_Block[ua]
233 .extern PRE_Block[ua]
234
235 #endif /* RIOS */
236
237 #ifdef mc68000
238 /*
239 #
240 # Information Technology Center
241 # Carnegie-Mellon University
242 #
243 #
244 */
245 .data
246
247 /*
248 #
249 # Process assembly language assist for Suns.
250 #
251 */
252
253 .text
254 .even
255
256 /*
257 #
258 # struct savearea {
259 # char *topstack;
260 # }
261 #
262 */
263
264 .globl _PRE_Block
265
266 topstack = 0
267
268 /* Stuff to allow saving/restoring registers */
269 nregs = 13
270 regs = 0x3ffe | d1-d7 & a0-a5
271
272 /*
273 # savecontext(f, area1, newsp)
274 # int (*f)(); struct savearea *area1; char *newsp;
275 */
276
277 /* Stack offsets of arguments */
278 f = 8
279 area1 = 12
280 newsp = 16
281
282 .globl _savecontext
283 _savecontext:
284 movb #1,_PRE_Block | Dont allow any interrupt finagling
285 link a6,#-(nregs*4) | Save frame pointer & ...
286 | ... allocate space for nregs registers
287 /* Save registers */
288 moveml #regs,sp@
289
290 movl a6@(area1),a0 | a0 = base of savearea
291 movl sp,a0@(topstack) | area->topstack = sp
292 movl a6@(newsp),d0 | Get new sp
293 jeq forw1 | If newsp == 0, no stack switch
294 movl d0,sp | Switch to new stack
295 forw1:
296 movl a6@(f),a0 | a0 = f
297 jbsr a0@ | f()
298
299 /* It is impossible to be here, so abort() */
300
301 jbsr _abort
302
303 /*
304 # returnto(area2)
305 # struct savearea *area2;
306 */
307
308 /* Stack offset of argument */
309 area2 = 8
310
311 .globl _returnto
312 _returnto:
313 link a6,#0
314 movl a6@(area2),a0 | Base of savearea
315 movl a0@(topstack),sp | Restore sp
316 /* Restore registers */
317 moveml sp@,#regs
318
319 addl #(nregs*4),sp
320 movl sp,a6 | Argghh...be careful here
321 unlk a6
322 clrb _PRE_Block
323 rts | Return to previous process
324 #endif /* mc68000 */
325 #ifdef sparc
326 #ifdef AFS_SUN5_ENV
327 #define _ASM 1
328 #include <sys/asm_linkage.h>
329 #include <sys/trap.h>
330 #else
331 #ifdef AFS_XBSD_ENV
332 #include <machine/trap.h>
333 #define ST_FLUSH_WINDOWS ST_FLUSHWIN
334 #define MINFRAME 92
335 #define SA(x) (((x)+7)&~7)
336 #define STACK_ALIGN 8
337 #else /* SunOS 4: */
338 #include <sun4/asm_linkage.h>
339 #include <sun4/trap.h>
340 #endif
341 #endif
342 .data
343 #ifdef AFS_SUN5_ENV
344 .globl PRE_Block
345 #else
346 .globl _PRE_Block
347 #endif
348 topstack = 0
349 globals = 4
350 /*
351 # savecontext(f, area1, newsp)
352 # int (*f)(); struct savearea *area1; char *newsp;
353 */
354 .text
355 #ifdef AFS_SUN5_ENV
356 .globl savecontext
357 savecontext:
358 #else
359 .globl _savecontext
360 _savecontext:
361 #endif
362 save %sp, -SA(MINFRAME), %sp ! Get new window
363 ta ST_FLUSH_WINDOWS ! FLush all other active windows
364
365 /* The following 3 lines do the equivalent of: _PRE_Block = 1 */
366 #ifdef AFS_SUN5_ENV
367 set PRE_Block, %l0
368 #else
369 set _PRE_Block, %l0
370 #endif
371 mov 1,%l1
372 stb %l1, [%l0]
373
374 st %fp,[%i1+topstack] ! area1->topstack = sp
375
376 st %g1, [%i1 + globals + 0] /* Save all globals just in case */
377 st %g2, [%i1 + globals + 4]
378 st %g3, [%i1 + globals + 8]
379 st %g4, [%i1 + globals + 12]
380 st %g5, [%i1 + globals + 16]
381 st %g6, [%i1 + globals + 20]
382 st %g7, [%i1 + globals + 24]
383 mov %y, %g1
384 st %g1, [%i1 + globals + 28]
385
386 #ifdef save_allregs
387 st %f0, [%i1 + globals + 32 + 0] ! Save all floating point registers
388 st %f1, [%i1 + globals + 32 + 4]
389 st %f2, [%i1 + globals + 32 + 8]
390 st %f3, [%i1 + globals + 32 + 12]
391 st %f4, [%i1 + globals + 32 + 16]
392 st %f5, [%i1 + globals + 32 + 20]
393 st %f6, [%i1 + globals + 32 + 24]
394 st %f7, [%i1 + globals + 32 + 28]
395 st %f8, [%i1 + globals + 64 + 0]
396 st %f9, [%i1 + globals + 64 + 4]
397 st %f10, [%i1 + globals + 64 + 8]
398 st %f11, [%i1 + globals + 64 + 12]
399 st %f12, [%i1 + globals + 64 + 16]
400 st %f13, [%i1 + globals + 64 + 20]
401 st %f14, [%i1 + globals + 64 + 24]
402 st %f15, [%i1 + globals + 64 + 28]
403 st %f16, [%i1 + globals + 64 + 32]
404 st %f17, [%i1 + globals + 64 + 36]
405 st %f18, [%i1 + globals + 64 + 40]
406 st %f19, [%i1 + globals + 64 + 44]
407 st %f20, [%i1 + globals + 64 + 48]
408 st %f21, [%i1 + globals + 64 + 52]
409 st %f22, [%i1 + globals + 64 + 56]
410 st %f23, [%i1 + globals + 64 + 60]
411 st %f24, [%i1 + globals + 64 + 64]
412 st %f25, [%i1 + globals + 64 + 68]
413 st %f26, [%i1 + globals + 64 + 72]
414 st %f27, [%i1 + globals + 64 + 76]
415 st %f28, [%i1 + globals + 64 + 80]
416 st %f29, [%i1 + globals + 64 + 84]
417 st %f30, [%i1 + globals + 64 + 88]
418 st %f31, [%i1 + globals + 64 + 92]
419 #ifdef notdef
420 mov %fsr,%g1
421 st %g1, [%i1 + globals + 64 + 96]
422 mov %fq,%g1
423 st %g1, [%i1 + globals + 64 + 100]
424 #endif
425
426 st %c0, [%i1 + globals + 168 + 0] ! Save all coprocessor registers
427 st %c1, [%i1 + globals + 168 + 4]
428 st %c2, [%i1 + globals + 168 + 8]
429 st %c3, [%i1 + globals + 168 + 12]
430 st %c4, [%i1 + globals + 168 + 16]
431 st %c5, [%i1 + globals + 168 + 20]
432 st %c6, [%i1 + globals + 168 + 24]
433 st %c7, [%i1 + globals + 168 + 28]
434 st %c8, [%i1 + globals + 200 + 0]
435 st %c9, [%i1 + globals + 200 + 4]
436 st %c10, [%i1 + globals + 200 + 8]
437 st %c11, [%i1 + globals + 200 + 12]
438 st %c12, [%i1 + globals + 200 + 16]
439 st %c13, [%i1 + globals + 200 + 20]
440 st %c14, [%i1 + globals + 200 + 24]
441 st %c15, [%i1 + globals + 200 + 28]
442 st %c16, [%i1 + globals + 200 + 32]
443 st %c17, [%i1 + globals + 200 + 36]
444 st %c18, [%i1 + globals + 200 + 40]
445 st %c19, [%i1 + globals + 200 + 44]
446 st %c20, [%i1 + globals + 200 + 48]
447 st %c21, [%i1 + globals + 200 + 52]
448 st %c22, [%i1 + globals + 200 + 56]
449 st %c23, [%i1 + globals + 200 + 60]
450 st %c24, [%i1 + globals + 200 + 64]
451 st %c25, [%i1 + globals + 200 + 68]
452 st %c26, [%i1 + globals + 200 + 72]
453 st %c27, [%i1 + globals + 200 + 76]
454 st %c28, [%i1 + globals + 200 + 80]
455 st %c29, [%i1 + globals + 200 + 84]
456 st %c30, [%i1 + globals + 200 + 88]
457 st %c31, [%i1 + globals + 200 + 92]
458 #ifdef notdef
459 mov %csr,%g1
460 st %g1, [%i1 + globals + 200 + 96]
461 mov %cq,%g1
462 st %g1, [%i1 + globals + 200 + 100]
463 #endif
464 #endif
465 cmp %i2, 0
466 be,a L1 ! if (newsp == 0) no stack switch
467 nop
468 #ifdef notdef
469 add %i2, STACK_ALIGN - 1, %i2
470 and %i2, ~(STACK_ALIGN - 1), %i2
471 sub %i2, SA(MINFRAME), %fp
472 call %i0
473 restore
474 #else
475 ! This used to compute a new stack frame base, write it into
476 ! FP, and restore to enter the new frame. But that left a window
477 ! in which FP could be written into the backing store for this
478 ! frame, to be tripped over later by returnto. So instead we do
479 ! the restore first, then modify SP to enter the new frame. We
480 ! can still refer to our argument as %02.
481 restore
482 add %o2, STACK_ALIGN - 1, %o2
483 and %o2, ~(STACK_ALIGN - 1), %o2
484 call %o0
485 sub %o2, SA(MINFRAME), %sp
486 #endif
487
488 L1: call %i0 ! call f()
489 nop
490
491
492 ! returnto(area1)
493 ! struct savearea *area1;
494 #ifdef AFS_SUN5_ENV
495 .globl returnto
496 returnto:
497 #else
498 .globl _returnto
499 _returnto:
500 #endif
501 ta ST_FLUSH_WINDOWS ! FLush all other active windows
502 ld [%o0+topstack],%g1 ! sp = area1->topstack
503 sub %g1, SA(MINFRAME), %fp ! Adjust sp to the right place
504 sub %fp, SA(MINFRAME), %sp
505
506 #ifdef save_allregs
507 ld [%o0 + globals + 32 + 0],%f0 ! Restore floating-point registers
508 ld [%o0 + globals + 32 + 4],%f1
509 ld [%o0 + globals + 32 + 8],%f2
510 ld [%o0 + globals + 32 + 12],%f3
511 ld [%o0 + globals + 32 + 16],%f4
512 ld [%o0 + globals + 32 + 20],%f5
513 ld [%o0 + globals + 32 + 24],%f6
514 ld [%o0 + globals + 32 + 28],%f7
515 ld [%o0 + globals + 64 + 0],%f8
516 ld [%o0 + globals + 64 + 4],%f9
517 ld [%o0 + globals + 64 + 8],%f10
518 ld [%o0 + globals + 64 + 12],%f11
519 ld [%o0 + globals + 64 + 16],%f12
520 ld [%o0 + globals + 64 + 20],%f13
521 ld [%o0 + globals + 64 + 24],%f14
522 ld [%o0 + globals + 64 + 28],%f15
523 ld [%o0 + globals + 64 + 32],%f16
524 ld [%o0 + globals + 64 + 36],%f17
525 ld [%o0 + globals + 64 + 40],%f18
526 ld [%o0 + globals + 64 + 44],%f19
527 ld [%o0 + globals + 64 + 48],%f20
528 ld [%o0 + globals + 64 + 52],%f21
529 ld [%o0 + globals + 64 + 56],%f22
530 ld [%o0 + globals + 64 + 60],%f23
531 ld [%o0 + globals + 64 + 64],%f24
532 ld [%o0 + globals + 64 + 68],%f25
533 ld [%o0 + globals + 64 + 72],%f26
534 ld [%o0 + globals + 64 + 76],%f27
535 ld [%o0 + globals + 64 + 80],%f28
536 ld [%o0 + globals + 64 + 84],%f29
537 ld [%o0 + globals + 64 + 88],%f30
538 ld [%o0 + globals + 64 + 92],%f31
539 #ifdef notdef
540 ld [%o0 + globals + 64 + 96],%g1
541 mov %g1, %fsr
542 ld [%o0 + globals + 64 + 100],%g1
543 mov %g1, %fq
544 #endif
545
546 ld [%o0 + globals + 168 + 0],%c0 ! Restore floating-point registers
547 ld [%o0 + globals + 168 + 4],%c1
548 ld [%o0 + globals + 168 + 8],%c2
549 ld [%o0 + globals + 168 + 12],%c3
550 ld [%o0 + globals + 168 + 16],%c4
551 ld [%o0 + globals + 168 + 20],%c5
552 ld [%o0 + globals + 168 + 24],%c6
553 ld [%o0 + globals + 168 + 28],%c7
554 ld [%o0 + globals + 200 + 0],%c8
555 ld [%o0 + globals + 200 + 4],%c9
556 ld [%o0 + globals + 200 + 8],%c10
557 ld [%o0 + globals + 200 + 12],%c11
558 ld [%o0 + globals + 200 + 16],%c12
559 ld [%o0 + globals + 200 + 20],%c13
560 ld [%o0 + globals + 200 + 24],%c14
561 ld [%o0 + globals + 200 + 28],%c15
562 ld [%o0 + globals + 200 + 32],%c16
563 ld [%o0 + globals + 200 + 36],%c17
564 ld [%o0 + globals + 200 + 40],%c18
565 ld [%o0 + globals + 200 + 44],%c19
566 ld [%o0 + globals + 200 + 48],%c20
567 ld [%o0 + globals + 200 + 52],%c21
568 ld [%o0 + globals + 200 + 56],%c22
569 ld [%o0 + globals + 200 + 60],%c23
570 ld [%o0 + globals + 200 + 64],%c24
571 ld [%o0 + globals + 200 + 68],%c25
572 ld [%o0 + globals + 200 + 72],%c26
573 ld [%o0 + globals + 200 + 76],%c27
574 ld [%o0 + globals + 200 + 80],%c28
575 ld [%o0 + globals + 200 + 84],%c29
576 ld [%o0 + globals + 200 + 88],%c30
577 ld [%o0 + globals + 200 + 92],%c31
578 #ifdef notdef
579 ld [%o0 + globals + 200 + 96],%g1
580 mov %g1, %csr
581 ld [%o0 + globals + 200 + 100],%g1
582 mov %g1, %cq
583 #endif
584 #endif
585 ld [%o0 + globals + 28], %g1 ! Restore global regs back
586 mov %g1, %y
587 ld [%o0 + globals + 0], %g1
588 ld [%o0 + globals + 4], %g2
589 ld [%o0 + globals + 8], %g3
590 ld [%o0 + globals + 12],%g4
591 ld [%o0 + globals + 16],%g5
592 ld [%o0 + globals + 20],%g6
593 ld [%o0 + globals + 24],%g7
594
595 /* The following 3 lines are equivalent to: _PRE_Block = 0 */
596 #ifdef AFS_SUN5_ENV
597 set PRE_Block, %l0
598 #else
599 set _PRE_Block, %l0
600 #endif
601 mov 0,%l1
602 stb %l1, [%l0]
603
604 restore
605 restore
606
607 retl
608 nop
609
610 #endif /* sparc */
611 #ifdef ibm032
612 |
613 | Information Technology Center
614 | Carnegie-Mellon University
615 |
616 |
617 .data
618 .globl .oVncs
619 .set .oVncs,0
620
621 .globl _savecontext
622 _savecontext:
623 .long _.savecontext
624
625 .globl _returnto
626 _returnto:
627 .long _.returnto
628
629 |
630 | Process assembly language assist for Sailboats.
631 |
632
633 .text
634 .align 2
635
636 |
637 | struct savearea {
638 | char *topstack;
639 | }
640 |
641
642 | Offsets of fields
643 .set topstack,0
644
645 | Stuff to allow saving/restoring registers
646 .set regspace,64
647 .set freg,0
648
649 |
650 | savecontext(f, area1, newsp)
651 | int (*f)(); struct savearea *area1; char *newsp;
652 |
653
654 .globl _.savecontext
655 _.savecontext:
656 ai sp,sp,-regspace | Save frame pointer & ...
657 | ... allocate space for 16 registers
658 | Save registers
659 stm r0,0(sp) | Change this if save fewer regs.
660 | Set preemption semaphore
661 get r6,$1
662 get r7,$_PRE_Block
663 putc r6,0(r7) | PRE_Block = 1
664 | r3 = base of savearea
665 put sp,topstack(r3) | area1->topstack = sp
666 | New sp is in r4.
667 cis r4,0
668 be L1 | If newsp == 0, no stack switch
669 cas sp,r4,r0 | Switch to new stack
670 L1:
671 get r6,0(r2) | r2 = _f
672 balrx r15,r6 | f()
673 cas r0,r2,r0
674
675 |
676 | returnto(area2)
677 | struct savearea *area2;
678 |
679
680 .globl _.returnto
681 _.returnto:
682 get sp,topstack(r2)
683 | Now in the context of the savecontext stack to be restored.
684 | Start with the registers...
685 | Clear preemption semaphore
686 get r6,$0
687 get r7,$_PRE_Block
688 putc r6,0(r7) | PRE_Block = 0
689 lm r0,0(sp) | Change if saving fewer regs.
690 brx r15 | Return to previous process
691 ai sp,sp,regspace
692 .data
693 .ltorg
694 #endif
695
696 #ifdef AFS_AIX22_ENV
697 /*
698 #
699 # Information Technology Center
700 # Carnegie-Mellon University
701 #
702 */
703 /*
704 #
705 # Process assembly language assist for Sailboats.
706 #
707 */
708
709 .text
710 .globl .savecontext
711 .align 1
712
713 /*
714 #
715 # struct savearea {
716 # char *topstack;
717 # }
718 #
719 */
720
721
722 /*# Offsets of fields*/
723 .set topstack,0
724
725 /*# Stuff to allow saving/restoring registers*/
726 .set regspace,64
727 .set freg,0
728
729 /*
730 #
731 # savecontext(f, area1, newsp)
732 # int (*f)(); struct savearea *area1; char *newsp;
733 #
734 */
735
736 .savecontext:
737 ai 1,1,-regspace # Save frame pointer & ...
738
739 /*# Save registers*/
740 stm 0,0(1) # Change this if save fewer regs.
741 lr 14,0
742 /*# Set preemption semaphore*/
743 lis 6,1
744 l 7,4(14)
745 stc 6,0(7)
746 /*# r3 = base of savearea*/
747 st 1,topstack(3) # area1->topstack = sp
748 /*# New sp is in r4.*/
749 ci 4,0
750 beq L1 # If newsp == 0, no stack switch
751 cas 1,4,0 # Switch to new stack
752 L1:
753 l 6,0(2) # r2 = _f
754 balrx 15,6 # f()
755 cas 0,2,0
756 .data 3
757 .globl _savecontext
758 _savecontext:
759 .long .savecontext
760 .long _PRE_Block
761 /*
762 #
763 # returnto(area2)
764 # struct savearea *area2;
765 #
766 */
767
768 .text
769 .globl .returnto
770 .align 1
771 .returnto:
772 l 1,topstack(2)
773 /*
774 # Now in the context of the savecontext stack to be restored.
775 # Start with the registers...
776 # Clear preemption semaphore
777 */
778 lr 14,0
779 lis 6,0
780 l 7,4(14)
781 stc 6,0(7)
782 lm 0,0(1) # Change if saving fewer regs.
783 brx 15 # Return to previous process
784 ai 1,1,regspace
785 .data 3
786 .globl _returnto
787 _returnto:
788 .long .returnto
789 .long _PRE_Block
790 #endif /* AFS_AIX_ENV */
791
792 #ifdef vax
793 /*
794 #
795 # Information Technology Center
796 # Carnegie-Mellon University
797 #
798 #
799 */
800 .data
801
802 /*
803 #
804 # Algorithm: "Monkey see, monkey do"
805 #
806 */
807
808 .text
809
810 /*
811 #
812 # struct savearea {
813 # char *topstack;
814 # }
815 #
816 */
817
818 .set topstack,0
819
820 /* Stuff to allow saving/restoring registers */
821
822 /*
823 # savecontext(f, area1, newsp)
824 # int (*f)(); struct savearea *area1; char *newsp;
825 */
826
827 /* Stack offsets of arguments */
828 .set f,4
829 .set area1,8
830 .set newsp,12
831
832 .globl _PRE_Block
833 .globl _savecontext
834
835 _savecontext:
836 .word 0x0ffc # Save regs R2-R11
837 movb $1,_PRE_Block # Critical section for preemption code
838 pushl ap # save old ap
839 pushl fp # save old fp
840 movl area1(ap),r0 # r0 = base of savearea
841 movl sp,topstack(r0) # area->topstack = sp
842 movl newsp(ap),r0 # Get new sp
843 beql L1 # if new sp is 0, dont change stacks
844 movl r0,sp # else switch to new stack
845 L1:
846 movl f(ap),r1 # r1 = f
847 calls $0,0(r1) # f()
848
849 /* It is impossible to be here, so abort() */
850
851 calls $0,_abort
852
853 /*
854 # returnto(area2)
855 # struct savearea *area2;
856 */
857
858 /* Stack offset of argument */
859 .set area2,4
860
861 .globl _returnto
862 _returnto:
863 .word 0x0 # Who cares about these regs?
864 movl area2(ap),r0 # r0 = address of area2
865 movl topstack(r0),sp # Restore sp
866 movl (sp)+,fp # Restore fp
867 movl (sp)+,ap # ,,,,
868 clrb _PRE_Block # End of preemption critical section
869 ret
870
871 pushl $1234 # The author will gloat
872 calls $0,_abort
873 #endif
874
875 #ifdef mips
876 #ifdef sgi
877 .option pic2
878
879 #include <regdef.h> /* Allow use of symbolic names for registers. */
880 /* 9 sregs, ra, 6 fp regs, gp, pad to 8 byte boundary */
881 #define regspace 9 * 4 + 4 + 6 * 8 + 4 + 4
882 #define floats 0
883 #define registers floats + 6 * 8
884 #define returnaddr regspace - 4
885 #define topstack 0
886 #define GPOFF regspace - 8
887 .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
888 .ent savecontext /* Insert debugger information. */
889 savecontext:
890 .set noreorder
891 .cpload t9 # set up gp for KPIC
892 .set reorder
893 subu sp, regspace
894 .cprestore GPOFF # trigger t9/jalr
895 .set noreorder
896 li t0, 1
897 .extern PRE_Block
898 sb t0, PRE_Block
899 .set reorder
900 .frame sp, regspace, ra
901 /* Save registers. */
902 sw s0, registers + 0(sp)
903 sw s1, registers + 4(sp)
904 sw s2, registers + 8(sp)
905 sw s3, registers + 12(sp)
906 sw s4, registers + 16(sp)
907 sw s5, registers + 20(sp)
908 sw s6, registers + 24(sp)
909 sw s7, registers + 28(sp)
910 sw s8, registers + 32(sp)
911 /* Save return address */
912 sw ra, returnaddr(sp)
913 .mask 0xc0ff0000, -4
914 /* Need to save floating point registers? */
915 s.d $f20, floats + 0(sp)
916 s.d $f22, floats + 8(sp)
917 s.d $f24, floats + 16(sp)
918 s.d $f26, floats + 24(sp)
919 s.d $f28, floats + 32(sp)
920 s.d $f30, floats + 40(sp)
921 .fmask 0x55400000, regspace
922 sw sp, topstack(a1)
923 beq a2, $0, samestack
924 move sp, a2
925 samestack:
926 move t9, a0
927 j t9
928 .end savecontext
929
930 .globl returnto
931 .ent returnto
932 returnto:
933 .set noreorder
934 .cpload t9 # set up gp for KPIC
935 .set reorder
936
937 lw sp, topstack(a0)
938 lw s0, registers + 0(sp)
939 lw s1, registers + 4(sp)
940 lw s2, registers + 8(sp)
941 lw s3, registers + 12(sp)
942 lw s4, registers + 16(sp)
943 lw s5, registers + 20(sp)
944 lw s6, registers + 24(sp)
945 lw s7, registers + 28(sp)
946 lw s8, registers + 32(sp)
947 /* Save return address */
948 lw ra, returnaddr(sp)
949 /* Need to save floating point registers? */
950 l.d $f20, floats + 0(sp)
951 l.d $f22, floats + 8(sp)
952 l.d $f24, floats + 16(sp)
953 l.d $f26, floats + 24(sp)
954 l.d $f28, floats + 32(sp)
955 l.d $f30, floats + 40(sp)
956 .set noreorder
957 addu sp, regspace
958 la t0, PRE_Block
959 j ra
960 sb zero, 0(t0)
961 .set reorder
962 .end returnto
963
964 #else
965 /* Code for MIPS R2000/R3000 architecture
966 * Written by Zalman Stern April 30th, 1989.
967 */
968 #include <regdef.h> /* Allow use of symbolic names for registers. */
969 #define regspace 9 * 4 + 4 + 6 * 8
970 #define floats 0
971 #define registers floats + 6 * 8
972 #define returnaddr regspace - 4
973 #define topstack 0
974 .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
975 .ent savecontext /* Insert debugger information. */
976 savecontext:
977 li t0, 1
978 .extern PRE_Block
979 sb t0, PRE_Block
980 subu sp, regspace
981 .frame sp, regspace, ra
982 /* Save registers. */
983 sw s0, registers + 0(sp)
984 sw s1, registers + 4(sp)
985 sw s2, registers + 8(sp)
986 sw s3, registers + 12(sp)
987 sw s4, registers + 16(sp)
988 sw s5, registers + 20(sp)
989 sw s6, registers + 24(sp)
990 sw s7, registers + 28(sp)
991 sw s8, registers + 32(sp)
992 /* Save return address */
993 sw ra, returnaddr(sp)
994 .mask 0xc0ff0000, -4
995 /* Need to save floating point registers? */
996 s.d $f20, floats + 0(sp)
997 s.d $f22, floats + 8(sp)
998 s.d $f24, floats + 16(sp)
999 s.d $f26, floats + 24(sp)
1000 s.d $f28, floats + 32(sp)
1001 s.d $f30, floats + 40(sp)
1002 .fmask 0x55400000, regspace
1003 sw sp, topstack(a1)
1004 beq a2, $0, samestack
1005 addu sp, $0, a2
1006 samestack:
1007 jal a0
1008 .end savecontext
1009
1010 .globl returnto
1011 .ent returnto
1012 returnto:
1013 lw sp, topstack(a0)
1014 lw s0, registers + 0(sp)
1015 lw s1, registers + 4(sp)
1016 lw s2, registers + 8(sp)
1017 lw s3, registers + 12(sp)
1018 lw s4, registers + 16(sp)
1019 lw s5, registers + 20(sp)
1020 lw s6, registers + 24(sp)
1021 lw s7, registers + 28(sp)
1022 lw s8, registers + 32(sp)
1023 /* Save return address */
1024 lw ra, returnaddr(sp)
1025 /* Need to save floating point registers? */
1026 l.d $f20, floats + 0(sp)
1027 l.d $f22, floats + 8(sp)
1028 l.d $f24, floats + 16(sp)
1029 l.d $f26, floats + 24(sp)
1030 l.d $f28, floats + 32(sp)
1031 l.d $f30, floats + 40(sp)
1032 addu sp, regspace
1033 sb $0, PRE_Block
1034 j ra
1035 .end returnto
1036 #endif /* sgi */
1037 #endif
1038
1039 #ifdef AFS_HPUX_ENV
1040 #include "process.s.hpux"
1041 #endif /* AFS_HPUX_ENV */
1042
1043 #ifdef __alpha
1044 /* Code for DEC Alpha architecture */
1045 #ifdef AFS_OSF_ENV
1046 #include <machine/asm.h>
1047 #include <machine/regdef.h>
1048 #define fs0 $f2
1049 #define fs1 $f3
1050 #define fs2 $f4
1051 #define fs3 $f5
1052 #define fs4 $f6
1053 #define fs5 $f7
1054 #define fs6 $f8
1055 #define fs7 $f9
1056 #elif defined(AFS_XBSD_ENV)
1057 #include <machine/asm.h>
1058 #else /* !OSF && !XBSD */
1059 #include <mach/alpha/asm.h>
1060 #endif /* OSF */
1061
1062 #define FRAMESIZE ((8*8)+8+(7*8))
1063 #define floats 0
1064 #define registers (floats+(8*8))
1065 #define returnaddr (FRAMESIZE-8)
1066 #define topstack 0
1067
1068 #ifdef AFS_OSF_ENV
1069 IMPORT(PRE_Block,4)
1070 #endif
1071 .align 4
1072 #ifdef AFS_OSF_ENV
1073 NESTED(savecontext,FRAMESIZE,ra)
1074 #else /* OSF */
1075 NESTED(savecontext,3,FRAMESIZE,ra,0x0400f700,0x000003fc)
1076 #endif /* OSF */
1077 ldgp gp,0(pv)
1078 lda t0, 1(zero)
1079 stl t0, PRE_Block
1080 lda sp,-FRAMESIZE(sp)
1081 /* Save callee-saved registers. */
1082 stq s0, (registers+0) (sp)
1083 stq s1, (registers+8) (sp)
1084 stq s2, (registers+16) (sp)
1085 stq s3, (registers+24) (sp)
1086 stq s4, (registers+32) (sp)
1087 stq s5, (registers+40) (sp)
1088 stq s6, (registers+48) (sp)
1089 /* Save return address */
1090 stq ra, returnaddr(sp)
1091
1092 .mask (M_S0|M_S1|M_S2|M_S3|M_S4|M_S5|M_S6|M_RA), -FRAMESIZE
1093
1094 /* Save floating point registers */
1095 stt fs0, (floats+0) (sp)
1096 stt fs1, (floats+8) (sp)
1097 stt fs2, (floats+16) (sp)
1098 stt fs3, (floats+24) (sp)
1099 stt fs4, (floats+32) (sp)
1100 stt fs5, (floats+40) (sp)
1101 stt fs6, (floats+48) (sp)
1102 stt fs7, (floats+56) (sp)
1103
1104 .prologue 1
1105 stq sp, topstack(a1)
1106 or a0,zero,pv /* call point in pv */
1107 beq a2, samestack
1108 or a2,zero,sp /* switch stack */
1109 samestack:
1110 jsr ra,(pv),0 /* off we go */
1111 END(savecontext)
1112
1113 #ifdef AFS_OSF_ENV
1114 LEAF(returnto)
1115 #else
1116 LEAF(returnto,1)
1117 #endif
1118 ldgp gp,0(pv)
1119
1120 .prologue 1
1121 ldq sp, topstack(a0)
1122 /* Restore callee-saved regs */
1123 ldq s0, (registers+0) (sp)
1124 ldq s1, (registers+8) (sp)
1125 ldq s2, (registers+16) (sp)
1126 ldq s3, (registers+24) (sp)
1127 ldq s4, (registers+32) (sp)
1128 ldq s5, (registers+40) (sp)
1129 ldq s6, (registers+48) (sp)
1130 /* Return address */
1131 ldq ra, returnaddr(sp)
1132 /* Floating point registers */
1133 ldt fs0, (floats+0) (sp)
1134 ldt fs1, (floats+8) (sp)
1135 ldt fs2, (floats+16) (sp)
1136 ldt fs3, (floats+24) (sp)
1137 ldt fs4, (floats+32) (sp)
1138 ldt fs5, (floats+40) (sp)
1139 ldt fs6, (floats+48) (sp)
1140 ldt fs7, (floats+56) (sp)
1141 lda sp, FRAMESIZE(sp)
1142 stl zero, PRE_Block
1143 RET
1144 END(returnto)
1145 #endif
1146
1147 #ifdef AFS_PPC_ENV
1148 /* Comments:
1149 * 1. Registers R10..R31 and CR0..CR7 are saved
1150 * 2. "struct savearea" must hold at least 3 pointers (long)
1151 * 3. This code will only work on 32 bit machines (601..604), not 620
1152 * 4. No floating point registers are saved
1153 * 5. The save stack "frame" is bigger than absolutely necessary. The
1154 * PowerPC [AIX] ABI needs this extra space.
1155 */
1156
1157
1158 /* Mach-O assemblers */
1159 #if !defined(NeXT) && !defined(__APPLE__)
1160 #define r0 0
1161 #define r1 1
1162 #define r2 2
1163 #define r3 3
1164 #define r4 4
1165 #define r5 5
1166 #define r6 6
1167 #define r7 7
1168 #define r8 8
1169 #define r9 9
1170 #define r10 10
1171 #define r11 11
1172 #define r12 12
1173 #define r13 13
1174 #define r14 14
1175 #define r15 15
1176 #define r16 16
1177 #define r17 17
1178 #define r18 18
1179 #define r19 19
1180 #define r20 20
1181 #define r21 21
1182 #define r22 22
1183 #define r23 23
1184 #define r24 24
1185 #define r25 25
1186 #define r26 26
1187 #define r27 27
1188 #define r28 28
1189 #define r29 29
1190 #define r30 30
1191 #define r31 31
1192 #endif /* !NeXT && !__APPLE__ */
1193
1194
1195 /*
1196 * savecontext(int (*f)(), struct savearea *save, char *newsp)
1197 */
1198
1199 #define FRAME_SIZE (32*4)+(8*4)
1200 #define FRAME_OFFSET (8*4)
1201 #define TOP_OF_STACK (0*4)
1202 #define RETURN (1*4)
1203 #define CCR (2*4)
1204
1205 #if defined(NeXT) || defined(__APPLE__)
1206 .globl _savecontext
1207 _savecontext:
1208 lis r9,ha16(_PRE_Block) /* Disable interrupt fiddling */
1209 li r8,1
1210 stb r8,lo16(_PRE_Block)(r9)
1211 #else
1212 .globl savecontext
1213 savecontext:
1214 lis r9,PRE_Block@ha /* Disable interrupt fiddling */
1215 li r8,1
1216 stb r8,PRE_Block@l(r9)
1217 #endif /* NeXT || __APPLE__ */
1218 subi r1,r1,FRAME_SIZE
1219 mfcr r9
1220 stw r9,CCR(r4)
1221 stw r10,10*4+FRAME_OFFSET(r1) /* Save registers */
1222 stw r11,11*4+FRAME_OFFSET(r1)
1223 stw r12,12*4+FRAME_OFFSET(r1)
1224 stw r13,13*4+FRAME_OFFSET(r1)
1225 stw r14,14*4+FRAME_OFFSET(r1)
1226 stw r15,15*4+FRAME_OFFSET(r1)
1227 stw r16,16*4+FRAME_OFFSET(r1)
1228 stw r17,17*4+FRAME_OFFSET(r1)
1229 stw r18,18*4+FRAME_OFFSET(r1)
1230 stw r19,19*4+FRAME_OFFSET(r1)
1231 stw r20,20*4+FRAME_OFFSET(r1)
1232 stw r21,21*4+FRAME_OFFSET(r1)
1233 stw r22,22*4+FRAME_OFFSET(r1)
1234 stw r23,23*4+FRAME_OFFSET(r1)
1235 stw r24,24*4+FRAME_OFFSET(r1)
1236 stw r25,25*4+FRAME_OFFSET(r1)
1237 stw r26,26*4+FRAME_OFFSET(r1)
1238 stw r27,27*4+FRAME_OFFSET(r1)
1239 stw r28,28*4+FRAME_OFFSET(r1)
1240 stw r29,29*4+FRAME_OFFSET(r1)
1241 stw r30,30*4+FRAME_OFFSET(r1)
1242 stw r31,31*4+FRAME_OFFSET(r1)
1243 stw r1,TOP_OF_STACK(r4)
1244 cmpi 0,r5,0 /* New stack specified? */
1245 mflr r0
1246 stw r0,RETURN(r4)
1247 mtlr r3
1248 beq L1 /* No - don't muck with pointer */
1249
1250 mr r1,r5
1251 L1: blr /* Return */
1252
1253 /*
1254 * returnto(struct savearea *area)
1255 */
1256 #if defined(NeXT) || defined(__APPLE__)
1257 .globl _returnto
1258 _returnto:
1259 #else
1260 .globl returnto
1261 returnto:
1262 #endif /* NeXT || __APPLE__ */
1263 lwz r1,TOP_OF_STACK(r3) /* Update stack pointer */
1264 lwz r0,RETURN(r3) /* Get return address */
1265 mtlr r0
1266 lwz r4,CCR(r3)
1267 mtcrf 0xFF,r4
1268 lwz r10,10*4+FRAME_OFFSET(r1) /* Restore registers */
1269 lwz r11,11*4+FRAME_OFFSET(r1)
1270 lwz r12,12*4+FRAME_OFFSET(r1)
1271 lwz r13,13*4+FRAME_OFFSET(r1)
1272 lwz r14,14*4+FRAME_OFFSET(r1)
1273 lwz r15,15*4+FRAME_OFFSET(r1)
1274 lwz r16,16*4+FRAME_OFFSET(r1)
1275 lwz r17,17*4+FRAME_OFFSET(r1)
1276 lwz r18,18*4+FRAME_OFFSET(r1)
1277 lwz r19,19*4+FRAME_OFFSET(r1)
1278 lwz r20,20*4+FRAME_OFFSET(r1)
1279 lwz r21,21*4+FRAME_OFFSET(r1)
1280 lwz r22,22*4+FRAME_OFFSET(r1)
1281 lwz r23,23*4+FRAME_OFFSET(r1)
1282 lwz r24,24*4+FRAME_OFFSET(r1)
1283 lwz r25,25*4+FRAME_OFFSET(r1)
1284 lwz r26,26*4+FRAME_OFFSET(r1)
1285 lwz r27,27*4+FRAME_OFFSET(r1)
1286 lwz r28,28*4+FRAME_OFFSET(r1)
1287 lwz r29,29*4+FRAME_OFFSET(r1)
1288 lwz r30,30*4+FRAME_OFFSET(r1)
1289 lwz r31,31*4+FRAME_OFFSET(r1)
1290 #if defined(NeXT) || defined(__APPLE__)
1291 lis r9,ha16(_PRE_Block) /* Re-enable interrupt fiddling */
1292 li r8,0
1293 stb r8,lo16(_PRE_Block)(r9)
1294 #else
1295 lis r9,PRE_Block@ha /* Re-enable interrupt fiddling */
1296 li r8,0
1297 stb r8,PRE_Block@l(r9)
1298 #endif /* NeXT || __APPLE__ */
1299 addi r1,r1,FRAME_SIZE
1300 blr
1301 #endif
1302
1303 #if defined(__linux__) && defined(__ELF__)
1304 .section .note.GNU-stack,"",%progbits
1305 #endif