2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #define IGNORE_STDS_H 1
11 #include <afs/param.h>
13 #if defined(__arm32__) || defined(__arm__)
14 /* register definitions */
22 savecontext(f, area1, newsp)
23 int (*f)()#if defined(RIOS);
24 struct savearea *area1;
28 /* Arguments appear as: f in r0, area1 in r1, newsp in r2 */
33 .type savecontext, #function
37 stmfd sp!, {fp, ip, lr, pc}
39 @ stack r0 - r10, current fp
40 stmfd sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, fp}
42 @ check if newsp is zero
48 /* should never get here ... */
53 struct savearea *area2;
59 .type returnto, #function
63 ldmfd r0, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, fp}
64 @ return from function call
65 ldmea fp, {fp, sp, pc}
67 #endif /* __arm32__ or __arm__ */
70 /* I don't know if we have to save the TOC (R2) or not...
71 * Note that stack-frame is supposed to be aligned on
72 * a double-word boundary.
73 * For details about RIOS calling conventions
74 * see the Assembler manual and /usr/include/sys/asdef.s
79 * savecontext(f, area1, newsp)
80 * int (*f)(); struct savearea *area1; char *newsp;
102 .set szdsa, 8*nfprs+4*ngprs+linkarea+argarea
104 .csect .savecontext[PR]
105 .globl .savecontext[PR]
107 mflr r0 # save link register
110 * save floating point registers. Interleave some other stuff for
111 * timing reasons. Set up conditions and registers for branches
112 * early, so that processor can prefetch instructions.
122 l 11, 0(a_f) # r11 <- *(a_f)
127 cmpi cr0, a_newsp, 0 # cr0 <- (a_newsp :: 0)
133 mtlr 11 # set up lr early so prefetch works
139 st r0, 8(r1) # save return addr
145 st 12, 4(r1) # save CR
152 * save general-purpose registers
154 stm 12, -8*nfprs-4*ngprs(r1)# save the general-purpose regs
155 stu r1, -szdsa(r1) # dec SP and save back chain
157 l r7, PRE_Block.S(toc) # r7 <- &PRE_Block
158 cal r6, 1(r0) # r6 <- #1
159 stb r6, 0(r7) # r6 -> PRE_Block
161 st r1, topstack(a_area1) # save old SP
163 beq L1 # if (a_newsp == 0) goto L1
165 mr r1, r5 # r1 <- a_newsp -- load new SP
167 L1: brl # pc <- lr -- (*a_f)()
170 * returnto(area2) This is a little jumbled, I tried to interleave
171 * memory accesses with simple instructions for speed, and I tried to
172 * set up the link register and condition register reasonably early
173 * so that processor instruction prefetching might help us out a little.
180 l r1, topstack(a_area2) # r1 <- a_area2->topstack
181 cal r1, szdsa(r1) # pop off frame
182 l r7, PRE_Block.S(toc) # r7 <- &PRE_Block
184 l 8, 8(1) # restore lr
185 mtlr 8 # do it early so prefetch works
187 lm 12, -8*nfprs-4*ngprs(r1)
188 cal r6, 0(r0) # r6 <- #0
189 mtcrf 0x38, 12 # put back cr
190 stb r6, 0(r7) # r6 -> PRE_Block
214 brl # pc <- lr -- return
219 .tc PRE_Block[tc], PRE_Block[ua]
220 .extern PRE_Block[ua]
227 # Information Technology Center
228 # Carnegie-Mellon University
236 # Process assembly language assist for Suns.
255 /* Stuff to allow saving/restoring registers */
257 regs = 0x3ffe | d1-d7 & a0-a5
260 # savecontext(f, area1, newsp)
261 # int (*f)(); struct savearea *area1; char *newsp;
264 /* Stack offsets of arguments */
271 movb #1,_PRE_Block | Dont allow any interrupt finagling
272 link a6,#-(nregs*4) | Save frame pointer & ...
273 | ... allocate space for nregs registers
277 movl a6@(area1),a0 | a0 = base of savearea
278 movl sp,a0@(topstack) | area->topstack = sp
279 movl a6@(newsp),d0 | Get new sp
280 jeq forw1 | If newsp == 0, no stack switch
281 movl d0,sp | Switch to new stack
283 movl a6@(f),a0 | a0 = f
286 /* It is impossible to be here, so abort() */
292 # struct savearea *area2;
295 /* Stack offset of argument */
301 movl a6@(area2),a0 | Base of savearea
302 movl a0@(topstack),sp | Restore sp
303 /* Restore registers */
307 movl sp,a6 | Argghh...be careful here
310 rts | Return to previous process
315 #include <sys/asm_linkage.h>
316 #include <sys/trap.h>
319 #include <machine/trap.h>
320 #define ST_FLUSH_WINDOWS ST_FLUSHWIN
322 #define SA(x) (((x)+7)&~7)
323 #define STACK_ALIGN 8
325 #include <sun4/asm_linkage.h>
326 #include <sun4/trap.h>
338 # savecontext(f, area1, newsp)
339 # int (*f)(); struct savearea *area1; char *newsp;
349 save %sp, -SA(MINFRAME), %sp ! Get new window
350 ta ST_FLUSH_WINDOWS ! FLush all other active windows
352 /* The following 3 lines do the equivalent of: _PRE_Block = 1 */
361 st %fp,[%i1+topstack] ! area1->topstack = sp
363 st %g1, [%i1 + globals + 0] /* Save all globals just in case */
364 st %g2, [%i1 + globals + 4]
365 st %g3, [%i1 + globals + 8]
366 st %g4, [%i1 + globals + 12]
367 st %g5, [%i1 + globals + 16]
368 st %g6, [%i1 + globals + 20]
369 st %g7, [%i1 + globals + 24]
371 st %g1, [%i1 + globals + 28]
374 st %f0, [%i1 + globals + 32 + 0] ! Save all floating point registers
375 st %f1, [%i1 + globals + 32 + 4]
376 st %f2, [%i1 + globals + 32 + 8]
377 st %f3, [%i1 + globals + 32 + 12]
378 st %f4, [%i1 + globals + 32 + 16]
379 st %f5, [%i1 + globals + 32 + 20]
380 st %f6, [%i1 + globals + 32 + 24]
381 st %f7, [%i1 + globals + 32 + 28]
382 st %f8, [%i1 + globals + 64 + 0]
383 st %f9, [%i1 + globals + 64 + 4]
384 st %f10, [%i1 + globals + 64 + 8]
385 st %f11, [%i1 + globals + 64 + 12]
386 st %f12, [%i1 + globals + 64 + 16]
387 st %f13, [%i1 + globals + 64 + 20]
388 st %f14, [%i1 + globals + 64 + 24]
389 st %f15, [%i1 + globals + 64 + 28]
390 st %f16, [%i1 + globals + 64 + 32]
391 st %f17, [%i1 + globals + 64 + 36]
392 st %f18, [%i1 + globals + 64 + 40]
393 st %f19, [%i1 + globals + 64 + 44]
394 st %f20, [%i1 + globals + 64 + 48]
395 st %f21, [%i1 + globals + 64 + 52]
396 st %f22, [%i1 + globals + 64 + 56]
397 st %f23, [%i1 + globals + 64 + 60]
398 st %f24, [%i1 + globals + 64 + 64]
399 st %f25, [%i1 + globals + 64 + 68]
400 st %f26, [%i1 + globals + 64 + 72]
401 st %f27, [%i1 + globals + 64 + 76]
402 st %f28, [%i1 + globals + 64 + 80]
403 st %f29, [%i1 + globals + 64 + 84]
404 st %f30, [%i1 + globals + 64 + 88]
405 st %f31, [%i1 + globals + 64 + 92]
408 st %g1, [%i1 + globals + 64 + 96]
410 st %g1, [%i1 + globals + 64 + 100]
413 st %c0, [%i1 + globals + 168 + 0] ! Save all coprocessor registers
414 st %c1, [%i1 + globals + 168 + 4]
415 st %c2, [%i1 + globals + 168 + 8]
416 st %c3, [%i1 + globals + 168 + 12]
417 st %c4, [%i1 + globals + 168 + 16]
418 st %c5, [%i1 + globals + 168 + 20]
419 st %c6, [%i1 + globals + 168 + 24]
420 st %c7, [%i1 + globals + 168 + 28]
421 st %c8, [%i1 + globals + 200 + 0]
422 st %c9, [%i1 + globals + 200 + 4]
423 st %c10, [%i1 + globals + 200 + 8]
424 st %c11, [%i1 + globals + 200 + 12]
425 st %c12, [%i1 + globals + 200 + 16]
426 st %c13, [%i1 + globals + 200 + 20]
427 st %c14, [%i1 + globals + 200 + 24]
428 st %c15, [%i1 + globals + 200 + 28]
429 st %c16, [%i1 + globals + 200 + 32]
430 st %c17, [%i1 + globals + 200 + 36]
431 st %c18, [%i1 + globals + 200 + 40]
432 st %c19, [%i1 + globals + 200 + 44]
433 st %c20, [%i1 + globals + 200 + 48]
434 st %c21, [%i1 + globals + 200 + 52]
435 st %c22, [%i1 + globals + 200 + 56]
436 st %c23, [%i1 + globals + 200 + 60]
437 st %c24, [%i1 + globals + 200 + 64]
438 st %c25, [%i1 + globals + 200 + 68]
439 st %c26, [%i1 + globals + 200 + 72]
440 st %c27, [%i1 + globals + 200 + 76]
441 st %c28, [%i1 + globals + 200 + 80]
442 st %c29, [%i1 + globals + 200 + 84]
443 st %c30, [%i1 + globals + 200 + 88]
444 st %c31, [%i1 + globals + 200 + 92]
447 st %g1, [%i1 + globals + 200 + 96]
449 st %g1, [%i1 + globals + 200 + 100]
453 be,a L1 ! if (newsp == 0) no stack switch
456 add %i2, STACK_ALIGN - 1, %i2
457 and %i2, ~(STACK_ALIGN - 1), %i2
458 sub %i2, SA(MINFRAME), %fp
462 ! This used to compute a new stack frame base, write it into
463 ! FP, and restore to enter the new frame. But that left a window
464 ! in which FP could be written into the backing store for this
465 ! frame, to be tripped over later by returnto. So instead we do
466 ! the restore first, then modify SP to enter the new frame. We
467 ! can still refer to our argument as %02.
469 add %o2, STACK_ALIGN - 1, %o2
470 and %o2, ~(STACK_ALIGN - 1), %o2
472 sub %o2, SA(MINFRAME), %sp
475 L1: call %i0 ! call f()
480 ! struct savearea *area1;
488 ta ST_FLUSH_WINDOWS ! FLush all other active windows
489 ld [%o0+topstack],%g1 ! sp = area1->topstack
490 sub %g1, SA(MINFRAME), %fp ! Adjust sp to the right place
491 sub %fp, SA(MINFRAME), %sp
494 ld [%o0 + globals + 32 + 0],%f0 ! Restore floating-point registers
495 ld [%o0 + globals + 32 + 4],%f1
496 ld [%o0 + globals + 32 + 8],%f2
497 ld [%o0 + globals + 32 + 12],%f3
498 ld [%o0 + globals + 32 + 16],%f4
499 ld [%o0 + globals + 32 + 20],%f5
500 ld [%o0 + globals + 32 + 24],%f6
501 ld [%o0 + globals + 32 + 28],%f7
502 ld [%o0 + globals + 64 + 0],%f8
503 ld [%o0 + globals + 64 + 4],%f9
504 ld [%o0 + globals + 64 + 8],%f10
505 ld [%o0 + globals + 64 + 12],%f11
506 ld [%o0 + globals + 64 + 16],%f12
507 ld [%o0 + globals + 64 + 20],%f13
508 ld [%o0 + globals + 64 + 24],%f14
509 ld [%o0 + globals + 64 + 28],%f15
510 ld [%o0 + globals + 64 + 32],%f16
511 ld [%o0 + globals + 64 + 36],%f17
512 ld [%o0 + globals + 64 + 40],%f18
513 ld [%o0 + globals + 64 + 44],%f19
514 ld [%o0 + globals + 64 + 48],%f20
515 ld [%o0 + globals + 64 + 52],%f21
516 ld [%o0 + globals + 64 + 56],%f22
517 ld [%o0 + globals + 64 + 60],%f23
518 ld [%o0 + globals + 64 + 64],%f24
519 ld [%o0 + globals + 64 + 68],%f25
520 ld [%o0 + globals + 64 + 72],%f26
521 ld [%o0 + globals + 64 + 76],%f27
522 ld [%o0 + globals + 64 + 80],%f28
523 ld [%o0 + globals + 64 + 84],%f29
524 ld [%o0 + globals + 64 + 88],%f30
525 ld [%o0 + globals + 64 + 92],%f31
527 ld [%o0 + globals + 64 + 96],%g1
529 ld [%o0 + globals + 64 + 100],%g1
533 ld [%o0 + globals + 168 + 0],%c0 ! Restore floating-point registers
534 ld [%o0 + globals + 168 + 4],%c1
535 ld [%o0 + globals + 168 + 8],%c2
536 ld [%o0 + globals + 168 + 12],%c3
537 ld [%o0 + globals + 168 + 16],%c4
538 ld [%o0 + globals + 168 + 20],%c5
539 ld [%o0 + globals + 168 + 24],%c6
540 ld [%o0 + globals + 168 + 28],%c7
541 ld [%o0 + globals + 200 + 0],%c8
542 ld [%o0 + globals + 200 + 4],%c9
543 ld [%o0 + globals + 200 + 8],%c10
544 ld [%o0 + globals + 200 + 12],%c11
545 ld [%o0 + globals + 200 + 16],%c12
546 ld [%o0 + globals + 200 + 20],%c13
547 ld [%o0 + globals + 200 + 24],%c14
548 ld [%o0 + globals + 200 + 28],%c15
549 ld [%o0 + globals + 200 + 32],%c16
550 ld [%o0 + globals + 200 + 36],%c17
551 ld [%o0 + globals + 200 + 40],%c18
552 ld [%o0 + globals + 200 + 44],%c19
553 ld [%o0 + globals + 200 + 48],%c20
554 ld [%o0 + globals + 200 + 52],%c21
555 ld [%o0 + globals + 200 + 56],%c22
556 ld [%o0 + globals + 200 + 60],%c23
557 ld [%o0 + globals + 200 + 64],%c24
558 ld [%o0 + globals + 200 + 68],%c25
559 ld [%o0 + globals + 200 + 72],%c26
560 ld [%o0 + globals + 200 + 76],%c27
561 ld [%o0 + globals + 200 + 80],%c28
562 ld [%o0 + globals + 200 + 84],%c29
563 ld [%o0 + globals + 200 + 88],%c30
564 ld [%o0 + globals + 200 + 92],%c31
566 ld [%o0 + globals + 200 + 96],%g1
568 ld [%o0 + globals + 200 + 100],%g1
572 ld [%o0 + globals + 28], %g1 ! Restore global regs back
574 ld [%o0 + globals + 0], %g1
575 ld [%o0 + globals + 4], %g2
576 ld [%o0 + globals + 8], %g3
577 ld [%o0 + globals + 12],%g4
578 ld [%o0 + globals + 16],%g5
579 ld [%o0 + globals + 20],%g6
580 ld [%o0 + globals + 24],%g7
582 /* The following 3 lines are equivalent to: _PRE_Block = 0 */
600 | Information Technology Center
601 | Carnegie-Mellon University
617 | Process assembly language assist for Sailboats.
632 | Stuff to allow saving/restoring registers
637 | savecontext(f, area1, newsp)
638 | int (*f)(); struct savearea *area1; char *newsp;
643 ai sp,sp,-regspace | Save frame pointer & ...
644 | ... allocate space for 16 registers
646 stm r0,0(sp) | Change this if save fewer regs.
647 | Set preemption semaphore
650 putc r6,0(r7) | PRE_Block = 1
651 | r3 = base of savearea
652 put sp,topstack(r3) | area1->topstack = sp
655 be L1 | If newsp == 0, no stack switch
656 cas sp,r4,r0 | Switch to new stack
658 get r6,0(r2) | r2 = _f
664 | struct savearea *area2;
670 | Now in the context of the savecontext stack to be restored.
671 | Start with the registers...
672 | Clear preemption semaphore
675 putc r6,0(r7) | PRE_Block = 0
676 lm r0,0(sp) | Change if saving fewer regs.
677 brx r15 | Return to previous process
686 # Information Technology Center
687 # Carnegie-Mellon University
692 # Process assembly language assist for Sailboats.
709 /*# Offsets of fields*/
712 /*# Stuff to allow saving/restoring registers*/
718 # savecontext(f, area1, newsp)
719 # int (*f)(); struct savearea *area1; char *newsp;
724 ai 1,1,-regspace # Save frame pointer & ...
727 stm 0,0(1) # Change this if save fewer regs.
729 /*# Set preemption semaphore*/
733 /*# r3 = base of savearea*/
734 st 1,topstack(3) # area1->topstack = sp
735 /*# New sp is in r4.*/
737 beq L1 # If newsp == 0, no stack switch
738 cas 1,4,0 # Switch to new stack
751 # struct savearea *area2;
761 # Now in the context of the savecontext stack to be restored.
762 # Start with the registers...
763 # Clear preemption semaphore
769 lm 0,0(1) # Change if saving fewer regs.
770 brx 15 # Return to previous process
777 #endif /* AFS_AIX_ENV */
782 # Information Technology Center
783 # Carnegie-Mellon University
791 # Algorithm: "Monkey see, monkey do"
807 /* Stuff to allow saving/restoring registers */
810 # savecontext(f, area1, newsp)
811 # int (*f)(); struct savearea *area1; char *newsp;
814 /* Stack offsets of arguments */
823 .word 0x0ffc # Save regs R2-R11
824 movb $1,_PRE_Block # Critical section for preemption code
825 pushl ap # save old ap
826 pushl fp # save old fp
827 movl area1(ap),r0 # r0 = base of savearea
828 movl sp,topstack(r0) # area->topstack = sp
829 movl newsp(ap),r0 # Get new sp
830 beql L1 # if new sp is 0, dont change stacks
831 movl r0,sp # else switch to new stack
833 movl f(ap),r1 # r1 = f
836 /* It is impossible to be here, so abort() */
842 # struct savearea *area2;
845 /* Stack offset of argument */
850 .word 0x0 # Who cares about these regs?
851 movl area2(ap),r0 # r0 = address of area2
852 movl topstack(r0),sp # Restore sp
853 movl (sp)+,fp # Restore fp
855 clrb _PRE_Block # End of preemption critical section
858 pushl $1234 # The author will gloat
866 #include <regdef.h> /* Allow use of symbolic names for registers. */
867 /* 9 sregs, ra, 6 fp regs, gp, pad to 8 byte boundary */
868 #define regspace 9 * 4 + 4 + 6 * 8 + 4 + 4
870 #define registers floats + 6 * 8
871 #define returnaddr regspace - 4
873 #define GPOFF regspace - 8
874 .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
875 .ent savecontext /* Insert debugger information. */
878 .cpload t9 # set up gp for KPIC
881 .cprestore GPOFF # trigger t9/jalr
887 .frame sp, regspace, ra
888 /* Save registers. */
889 sw s0, registers + 0(sp)
890 sw s1, registers + 4(sp)
891 sw s2, registers + 8(sp)
892 sw s3, registers + 12(sp)
893 sw s4, registers + 16(sp)
894 sw s5, registers + 20(sp)
895 sw s6, registers + 24(sp)
896 sw s7, registers + 28(sp)
897 sw s8, registers + 32(sp)
898 /* Save return address */
899 sw ra, returnaddr(sp)
901 /* Need to save floating point registers? */
902 s.d $f20, floats + 0(sp)
903 s.d $f22, floats + 8(sp)
904 s.d $f24, floats + 16(sp)
905 s.d $f26, floats + 24(sp)
906 s.d $f28, floats + 32(sp)
907 s.d $f30, floats + 40(sp)
908 .fmask 0x55400000, regspace
910 beq a2, $0, samestack
921 .cpload t9 # set up gp for KPIC
925 lw s0, registers + 0(sp)
926 lw s1, registers + 4(sp)
927 lw s2, registers + 8(sp)
928 lw s3, registers + 12(sp)
929 lw s4, registers + 16(sp)
930 lw s5, registers + 20(sp)
931 lw s6, registers + 24(sp)
932 lw s7, registers + 28(sp)
933 lw s8, registers + 32(sp)
934 /* Save return address */
935 lw ra, returnaddr(sp)
936 /* Need to save floating point registers? */
937 l.d $f20, floats + 0(sp)
938 l.d $f22, floats + 8(sp)
939 l.d $f24, floats + 16(sp)
940 l.d $f26, floats + 24(sp)
941 l.d $f28, floats + 32(sp)
942 l.d $f30, floats + 40(sp)
952 /* Code for MIPS R2000/R3000 architecture
953 * Written by Zalman Stern April 30th, 1989.
955 #include <regdef.h> /* Allow use of symbolic names for registers. */
956 #define regspace 9 * 4 + 4 + 6 * 8
958 #define registers floats + 6 * 8
959 #define returnaddr regspace - 4
961 .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
962 .ent savecontext /* Insert debugger information. */
968 .frame sp, regspace, ra
969 /* Save registers. */
970 sw s0, registers + 0(sp)
971 sw s1, registers + 4(sp)
972 sw s2, registers + 8(sp)
973 sw s3, registers + 12(sp)
974 sw s4, registers + 16(sp)
975 sw s5, registers + 20(sp)
976 sw s6, registers + 24(sp)
977 sw s7, registers + 28(sp)
978 sw s8, registers + 32(sp)
979 /* Save return address */
980 sw ra, returnaddr(sp)
982 /* Need to save floating point registers? */
983 s.d $f20, floats + 0(sp)
984 s.d $f22, floats + 8(sp)
985 s.d $f24, floats + 16(sp)
986 s.d $f26, floats + 24(sp)
987 s.d $f28, floats + 32(sp)
988 s.d $f30, floats + 40(sp)
989 .fmask 0x55400000, regspace
991 beq a2, $0, samestack
1001 lw s0, registers + 0(sp)
1002 lw s1, registers + 4(sp)
1003 lw s2, registers + 8(sp)
1004 lw s3, registers + 12(sp)
1005 lw s4, registers + 16(sp)
1006 lw s5, registers + 20(sp)
1007 lw s6, registers + 24(sp)
1008 lw s7, registers + 28(sp)
1009 lw s8, registers + 32(sp)
1010 /* Save return address */
1011 lw ra, returnaddr(sp)
1012 /* Need to save floating point registers? */
1013 l.d $f20, floats + 0(sp)
1014 l.d $f22, floats + 8(sp)
1015 l.d $f24, floats + 16(sp)
1016 l.d $f26, floats + 24(sp)
1017 l.d $f28, floats + 32(sp)
1018 l.d $f30, floats + 40(sp)
1027 #include "process.s.hpux"
1028 #endif /* AFS_HPUX_ENV */
1031 /* Code for DEC Alpha architecture */
1033 #include <machine/asm.h>
1034 #include <machine/regdef.h>
1043 #elif defined(AFS_XBSD_ENV)
1044 #include <machine/asm.h>
1045 #else /* !OSF && !XBSD */
1046 #include <mach/alpha/asm.h>
1049 #define FRAMESIZE ((8*8)+8+(7*8))
1051 #define registers (floats+(8*8))
1052 #define returnaddr (FRAMESIZE-8)
1060 NESTED(savecontext,FRAMESIZE,ra)
1062 NESTED(savecontext,3,FRAMESIZE,ra,0x0400f700,0x000003fc)
1067 lda sp,-FRAMESIZE(sp)
1068 /* Save callee-saved registers. */
1069 stq s0, (registers+0) (sp)
1070 stq s1, (registers+8) (sp)
1071 stq s2, (registers+16) (sp)
1072 stq s3, (registers+24) (sp)
1073 stq s4, (registers+32) (sp)
1074 stq s5, (registers+40) (sp)
1075 stq s6, (registers+48) (sp)
1076 /* Save return address */
1077 stq ra, returnaddr(sp)
1079 .mask (M_S0|M_S1|M_S2|M_S3|M_S4|M_S5|M_S6|M_RA), -FRAMESIZE
1081 /* Save floating point registers */
1082 stt fs0, (floats+0) (sp)
1083 stt fs1, (floats+8) (sp)
1084 stt fs2, (floats+16) (sp)
1085 stt fs3, (floats+24) (sp)
1086 stt fs4, (floats+32) (sp)
1087 stt fs5, (floats+40) (sp)
1088 stt fs6, (floats+48) (sp)
1089 stt fs7, (floats+56) (sp)
1092 stq sp, topstack(a1)
1093 or a0,zero,pv /* call point in pv */
1095 or a2,zero,sp /* switch stack */
1097 jsr ra,(pv),0 /* off we go */
1108 ldq sp, topstack(a0)
1109 /* Restore callee-saved regs */
1110 ldq s0, (registers+0) (sp)
1111 ldq s1, (registers+8) (sp)
1112 ldq s2, (registers+16) (sp)
1113 ldq s3, (registers+24) (sp)
1114 ldq s4, (registers+32) (sp)
1115 ldq s5, (registers+40) (sp)
1116 ldq s6, (registers+48) (sp)
1117 /* Return address */
1118 ldq ra, returnaddr(sp)
1119 /* Floating point registers */
1120 ldt fs0, (floats+0) (sp)
1121 ldt fs1, (floats+8) (sp)
1122 ldt fs2, (floats+16) (sp)
1123 ldt fs3, (floats+24) (sp)
1124 ldt fs4, (floats+32) (sp)
1125 ldt fs5, (floats+40) (sp)
1126 ldt fs6, (floats+48) (sp)
1127 ldt fs7, (floats+56) (sp)
1128 lda sp, FRAMESIZE(sp)
1136 * 1. Registers R10..R31 and CR0..CR7 are saved
1137 * 2. "struct savearea" must hold at least 3 pointers (long)
1138 * 3. This code will only work on 32 bit machines (601..604), not 620
1139 * 4. No floating point registers are saved
1140 * 5. The save stack "frame" is bigger than absolutely necessary. The
1141 * PowerPC [AIX] ABI needs this extra space.
1145 /* Mach-O assemblers */
1146 #if !defined(NeXT) && !defined(__APPLE__)
1179 #endif /* !NeXT && !__APPLE__ */
1183 * savecontext(int (*f)(), struct savearea *save, char *newsp)
1186 #define FRAME_SIZE (32*4)+(8*4)
1187 #define FRAME_OFFSET (8*4)
1188 #define TOP_OF_STACK (0*4)
1189 #define RETURN (1*4)
1192 #if defined(NeXT) || defined(__APPLE__)
1195 lis r9,ha16(_PRE_Block) /* Disable interrupt fiddling */
1197 stb r8,lo16(_PRE_Block)(r9)
1201 lis r9,PRE_Block@ha /* Disable interrupt fiddling */
1203 stb r8,PRE_Block@l(r9)
1204 #endif /* NeXT || __APPLE__ */
1205 subi r1,r1,FRAME_SIZE
1208 stw r10,10*4+FRAME_OFFSET(r1) /* Save registers */
1209 stw r11,11*4+FRAME_OFFSET(r1)
1210 stw r12,12*4+FRAME_OFFSET(r1)
1211 stw r13,13*4+FRAME_OFFSET(r1)
1212 stw r14,14*4+FRAME_OFFSET(r1)
1213 stw r15,15*4+FRAME_OFFSET(r1)
1214 stw r16,16*4+FRAME_OFFSET(r1)
1215 stw r17,17*4+FRAME_OFFSET(r1)
1216 stw r18,18*4+FRAME_OFFSET(r1)
1217 stw r19,19*4+FRAME_OFFSET(r1)
1218 stw r20,20*4+FRAME_OFFSET(r1)
1219 stw r21,21*4+FRAME_OFFSET(r1)
1220 stw r22,22*4+FRAME_OFFSET(r1)
1221 stw r23,23*4+FRAME_OFFSET(r1)
1222 stw r24,24*4+FRAME_OFFSET(r1)
1223 stw r25,25*4+FRAME_OFFSET(r1)
1224 stw r26,26*4+FRAME_OFFSET(r1)
1225 stw r27,27*4+FRAME_OFFSET(r1)
1226 stw r28,28*4+FRAME_OFFSET(r1)
1227 stw r29,29*4+FRAME_OFFSET(r1)
1228 stw r30,30*4+FRAME_OFFSET(r1)
1229 stw r31,31*4+FRAME_OFFSET(r1)
1230 stw r1,TOP_OF_STACK(r4)
1231 cmpi 0,r5,0 /* New stack specified? */
1235 beq L1 /* No - don't muck with pointer */
1238 L1: blr /* Return */
1241 * returnto(struct savearea *area)
1243 #if defined(NeXT) || defined(__APPLE__)
1249 #endif /* NeXT || __APPLE__ */
1250 lwz r1,TOP_OF_STACK(r3) /* Update stack pointer */
1251 lwz r0,RETURN(r3) /* Get return address */
1255 lwz r10,10*4+FRAME_OFFSET(r1) /* Restore registers */
1256 lwz r11,11*4+FRAME_OFFSET(r1)
1257 lwz r12,12*4+FRAME_OFFSET(r1)
1258 lwz r13,13*4+FRAME_OFFSET(r1)
1259 lwz r14,14*4+FRAME_OFFSET(r1)
1260 lwz r15,15*4+FRAME_OFFSET(r1)
1261 lwz r16,16*4+FRAME_OFFSET(r1)
1262 lwz r17,17*4+FRAME_OFFSET(r1)
1263 lwz r18,18*4+FRAME_OFFSET(r1)
1264 lwz r19,19*4+FRAME_OFFSET(r1)
1265 lwz r20,20*4+FRAME_OFFSET(r1)
1266 lwz r21,21*4+FRAME_OFFSET(r1)
1267 lwz r22,22*4+FRAME_OFFSET(r1)
1268 lwz r23,23*4+FRAME_OFFSET(r1)
1269 lwz r24,24*4+FRAME_OFFSET(r1)
1270 lwz r25,25*4+FRAME_OFFSET(r1)
1271 lwz r26,26*4+FRAME_OFFSET(r1)
1272 lwz r27,27*4+FRAME_OFFSET(r1)
1273 lwz r28,28*4+FRAME_OFFSET(r1)
1274 lwz r29,29*4+FRAME_OFFSET(r1)
1275 lwz r30,30*4+FRAME_OFFSET(r1)
1276 lwz r31,31*4+FRAME_OFFSET(r1)
1277 #if defined(NeXT) || defined(__APPLE__)
1278 lis r9,ha16(_PRE_Block) /* Re-enable interrupt fiddling */
1280 stb r8,lo16(_PRE_Block)(r9)
1282 lis r9,PRE_Block@ha /* Re-enable interrupt fiddling */
1284 stb r8,PRE_Block@l(r9)
1285 #endif /* NeXT || __APPLE__ */
1286 addi r1,r1,FRAME_SIZE
1290 #if defined(__linux__) && defined(__ELF__)
1291 .section .note.GNU-stack,"",%progbits