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
12 #include <afs/param.h>
13 #endif /* AFS_DJGPP_ENV */
17 /* I don't know if we have to save the TOC (R2) or not...
18 * Note that stack-frame is supposed to be aligned on
19 * a double-word boundary.
20 * For details about RIOS calling conventions
21 * see the Assembler manual and /usr/include/sys/asdef.s
26 * savecontext(f, area1, newsp)
27 * int (*f)(); struct savearea *area1; char *newsp;
49 .set szdsa, 8*nfprs+4*ngprs+linkarea+argarea
51 .csect .savecontext[PR]
52 .globl .savecontext[PR]
54 mflr r0 # save link register
57 * save floating point registers. Interleave some other stuff for
58 * timing reasons. Set up conditions and registers for branches
59 * early, so that processor can prefetch instructions.
69 l 11, 0(a_f) # r11 <- *(a_f)
74 cmpi cr0, a_newsp, 0 # cr0 <- (a_newsp :: 0)
80 mtlr 11 # set up lr early so prefetch works
86 st r0, 8(r1) # save return addr
92 st 12, 4(r1) # save CR
99 * save general-purpose registers
101 stm 12, -8*nfprs-4*ngprs(r1)# save the general-purpose regs
102 stu r1, -szdsa(r1) # dec SP and save back chain
104 l r7, PRE_Block.S(toc) # r7 <- &PRE_Block
105 cal r6, 1(r0) # r6 <- #1
106 stb r6, 0(r7) # r6 -> PRE_Block
108 st r1, topstack(a_area1) # save old SP
110 beq L1 # if (a_newsp == 0) goto L1
112 mr r1, r5 # r1 <- a_newsp -- load new SP
114 L1: brl # pc <- lr -- (*a_f)()
117 * returnto(area2) This is a little jumbled, I tried to interleave
118 * memory accesses with simple instructions for speed, and I tried to
119 * set up the link register and condition register reasonably early
120 * so that processor instruction prefetching might help us out a little.
127 l r1, topstack(a_area2) # r1 <- a_area2->topstack
128 cal r1, szdsa(r1) # pop off frame
129 l r7, PRE_Block.S(toc) # r7 <- &PRE_Block
131 l 8, 8(1) # restore lr
132 mtlr 8 # do it early so prefetch works
134 lm 12, -8*nfprs-4*ngprs(r1)
135 cal r6, 0(r0) # r6 <- #0
136 mtcrf 0x38, 12 # put back cr
137 stb r6, 0(r7) # r6 -> PRE_Block
161 brl # pc <- lr -- return
166 .tc PRE_Block[tc], PRE_Block[ua]
167 .extern PRE_Block[ua]
170 #if defined(AFS_S390_LINUX20_ENV)
171 /* Linux for S/390 (31 bit)
173 * Written by Neale Ferguson <Neale.Ferguson@SoftwareAG-usa.com>
175 * additional munging by Adam Thornton <adam@sinenomine.net>
180 .type savecontext,%function
182 * savecontext(f, area1, newsp)
183 * int (*f)(); struct savearea *area1; char *newsp;
195 P_PRE: .long PRE_Block
199 stm %r6,%r15,24(%r15) /* Save our registers */
201 ahi %r15,-96 /* Move out of harm's way */
203 bras %r5,.L0 /* Get A(A(PRE_Block)) */
206 l %r5,0(%r5) /* Get A(PRE_Block) */
207 mvi 3(%r5),1 /* Set it */
208 lr %r6,%r3 /* Get base of savearea */
209 st %r15,0(%r3) /* Save stack pointer */
210 ltr %r4,%r4 /* If new sp is 0 */
211 jz .L1 /* ... don't change sp */
212 lr %r15,%r4 /* Set new stack pointer */
214 br %r2 /* Call the routine */
215 /* Can't get here....*/
224 .size savecontext,.savecontext_end-savecontext
228 * struct savearea *area2;
233 .type returnto,%function
235 l %r15,0(%r2) /* New frame, to get correct pointer*/
236 bras %r5,.L3 /* Get A(A(PRE_Block))
240 l %r5,0(%r5) /* Get A(PRE_Block) */
241 /*xc 0(4,%r5),0(%r5) /* Clear it */
242 mvi 3(%r5),0 /* Clear it */
244 lm %r6,%r15,24(%r15) /* Restore registers */
255 .size returnto,.returnto_end-returnto
256 #endif /* AFS_S390_LINUX20_ENV */
261 # Information Technology Center
262 # Carnegie-Mellon University
270 # Process assembly language assist for Suns.
289 /* Stuff to allow saving/restoring registers */
291 regs = 0x3ffe | d1-d7 & a0-a5
294 # savecontext(f, area1, newsp)
295 # int (*f)(); struct savearea *area1; char *newsp;
298 /* Stack offsets of arguments */
305 movb #1,_PRE_Block | Dont allow any interrupt finagling
306 link a6,#-(nregs*4) | Save frame pointer & ...
307 | ... allocate space for nregs registers
311 movl a6@(area1),a0 | a0 = base of savearea
312 movl sp,a0@(topstack) | area->topstack = sp
313 movl a6@(newsp),d0 | Get new sp
314 jeq forw1 | If newsp == 0, no stack switch
315 movl d0,sp | Switch to new stack
317 movl a6@(f),a0 | a0 = f
320 /* It is impossible to be here, so abort() */
326 # struct savearea *area2;
329 /* Stack offset of argument */
335 movl a6@(area2),a0 | Base of savearea
336 movl a0@(topstack),sp | Restore sp
337 /* Restore registers */
341 movl sp,a6 | Argghh...be careful here
344 rts | Return to previous process
349 #include <sys/asm_linkage.h>
350 #include <sys/trap.h>
352 #include <sun4/asm_linkage.h>
353 #include <sun4/trap.h>
364 # savecontext(f, area1, newsp)
365 # int (*f)(); struct savearea *area1; char *newsp;
375 save %sp, -SA(MINFRAME), %sp ! Get new window
376 ta ST_FLUSH_WINDOWS ! FLush all other active windows
378 /* The following 3 lines do the equivalent of: _PRE_Block = 1 */
387 st %fp,[%i1+topstack] ! area1->topstack = sp
389 st %g1, [%i1 + globals + 0] /* Save all globals just in case */
390 st %g2, [%i1 + globals + 4]
391 st %g3, [%i1 + globals + 8]
392 st %g4, [%i1 + globals + 12]
393 st %g5, [%i1 + globals + 16]
394 st %g6, [%i1 + globals + 20]
395 st %g7, [%i1 + globals + 24]
397 st %g1, [%i1 + globals + 28]
400 st %f0, [%i1 + globals + 32 + 0] ! Save all floating point registers
401 st %f1, [%i1 + globals + 32 + 4]
402 st %f2, [%i1 + globals + 32 + 8]
403 st %f3, [%i1 + globals + 32 + 12]
404 st %f4, [%i1 + globals + 32 + 16]
405 st %f5, [%i1 + globals + 32 + 20]
406 st %f6, [%i1 + globals + 32 + 24]
407 st %f7, [%i1 + globals + 32 + 28]
408 st %f8, [%i1 + globals + 64 + 0]
409 st %f9, [%i1 + globals + 64 + 4]
410 st %f10, [%i1 + globals + 64 + 8]
411 st %f11, [%i1 + globals + 64 + 12]
412 st %f12, [%i1 + globals + 64 + 16]
413 st %f13, [%i1 + globals + 64 + 20]
414 st %f14, [%i1 + globals + 64 + 24]
415 st %f15, [%i1 + globals + 64 + 28]
416 st %f16, [%i1 + globals + 64 + 32]
417 st %f17, [%i1 + globals + 64 + 36]
418 st %f18, [%i1 + globals + 64 + 40]
419 st %f19, [%i1 + globals + 64 + 44]
420 st %f20, [%i1 + globals + 64 + 48]
421 st %f21, [%i1 + globals + 64 + 52]
422 st %f22, [%i1 + globals + 64 + 56]
423 st %f23, [%i1 + globals + 64 + 60]
424 st %f24, [%i1 + globals + 64 + 64]
425 st %f25, [%i1 + globals + 64 + 68]
426 st %f26, [%i1 + globals + 64 + 72]
427 st %f27, [%i1 + globals + 64 + 76]
428 st %f28, [%i1 + globals + 64 + 80]
429 st %f29, [%i1 + globals + 64 + 84]
430 st %f30, [%i1 + globals + 64 + 88]
431 st %f31, [%i1 + globals + 64 + 92]
434 st %g1, [%i1 + globals + 64 + 96]
436 st %g1, [%i1 + globals + 64 + 100]
439 st %c0, [%i1 + globals + 168 + 0] ! Save all coprocessor registers
440 st %c1, [%i1 + globals + 168 + 4]
441 st %c2, [%i1 + globals + 168 + 8]
442 st %c3, [%i1 + globals + 168 + 12]
443 st %c4, [%i1 + globals + 168 + 16]
444 st %c5, [%i1 + globals + 168 + 20]
445 st %c6, [%i1 + globals + 168 + 24]
446 st %c7, [%i1 + globals + 168 + 28]
447 st %c8, [%i1 + globals + 200 + 0]
448 st %c9, [%i1 + globals + 200 + 4]
449 st %c10, [%i1 + globals + 200 + 8]
450 st %c11, [%i1 + globals + 200 + 12]
451 st %c12, [%i1 + globals + 200 + 16]
452 st %c13, [%i1 + globals + 200 + 20]
453 st %c14, [%i1 + globals + 200 + 24]
454 st %c15, [%i1 + globals + 200 + 28]
455 st %c16, [%i1 + globals + 200 + 32]
456 st %c17, [%i1 + globals + 200 + 36]
457 st %c18, [%i1 + globals + 200 + 40]
458 st %c19, [%i1 + globals + 200 + 44]
459 st %c20, [%i1 + globals + 200 + 48]
460 st %c21, [%i1 + globals + 200 + 52]
461 st %c22, [%i1 + globals + 200 + 56]
462 st %c23, [%i1 + globals + 200 + 60]
463 st %c24, [%i1 + globals + 200 + 64]
464 st %c25, [%i1 + globals + 200 + 68]
465 st %c26, [%i1 + globals + 200 + 72]
466 st %c27, [%i1 + globals + 200 + 76]
467 st %c28, [%i1 + globals + 200 + 80]
468 st %c29, [%i1 + globals + 200 + 84]
469 st %c30, [%i1 + globals + 200 + 88]
470 st %c31, [%i1 + globals + 200 + 92]
473 st %g1, [%i1 + globals + 200 + 96]
475 st %g1, [%i1 + globals + 200 + 100]
479 be,a L1 ! if (newsp == 0) no stack switch
482 add %i2, STACK_ALIGN - 1, %i2
483 and %i2, ~(STACK_ALIGN - 1), %i2
484 sub %i2, SA(MINFRAME), %fp
488 ! This used to compute a new stack frame base, write it into
489 ! FP, and restore to enter the new frame. But that left a window
490 ! in which FP could be written into the backing store for this
491 ! frame, to be tripped over later by returnto. So instead we do
492 ! the restore first, then modify SP to enter the new frame. We
493 ! can still refer to our argument as %02.
495 add %o2, STACK_ALIGN - 1, %o2
496 and %o2, ~(STACK_ALIGN - 1), %o2
498 sub %o2, SA(MINFRAME), %sp
501 L1: call %i0 ! call f()
506 ! struct savearea *area1;
514 ta ST_FLUSH_WINDOWS ! FLush all other active windows
515 ld [%o0+topstack],%g1 ! sp = area1->topstack
516 sub %g1, SA(MINFRAME), %fp ! Adjust sp to the right place
517 sub %fp, SA(MINFRAME), %sp
520 ld [%o0 + globals + 32 + 0],%f0 ! Restore floating-point registers
521 ld [%o0 + globals + 32 + 4],%f1
522 ld [%o0 + globals + 32 + 8],%f2
523 ld [%o0 + globals + 32 + 12],%f3
524 ld [%o0 + globals + 32 + 16],%f4
525 ld [%o0 + globals + 32 + 20],%f5
526 ld [%o0 + globals + 32 + 24],%f6
527 ld [%o0 + globals + 32 + 28],%f7
528 ld [%o0 + globals + 64 + 0],%f8
529 ld [%o0 + globals + 64 + 4],%f9
530 ld [%o0 + globals + 64 + 8],%f10
531 ld [%o0 + globals + 64 + 12],%f11
532 ld [%o0 + globals + 64 + 16],%f12
533 ld [%o0 + globals + 64 + 20],%f13
534 ld [%o0 + globals + 64 + 24],%f14
535 ld [%o0 + globals + 64 + 28],%f15
536 ld [%o0 + globals + 64 + 32],%f16
537 ld [%o0 + globals + 64 + 36],%f17
538 ld [%o0 + globals + 64 + 40],%f18
539 ld [%o0 + globals + 64 + 44],%f19
540 ld [%o0 + globals + 64 + 48],%f20
541 ld [%o0 + globals + 64 + 52],%f21
542 ld [%o0 + globals + 64 + 56],%f22
543 ld [%o0 + globals + 64 + 60],%f23
544 ld [%o0 + globals + 64 + 64],%f24
545 ld [%o0 + globals + 64 + 68],%f25
546 ld [%o0 + globals + 64 + 72],%f26
547 ld [%o0 + globals + 64 + 76],%f27
548 ld [%o0 + globals + 64 + 80],%f28
549 ld [%o0 + globals + 64 + 84],%f29
550 ld [%o0 + globals + 64 + 88],%f30
551 ld [%o0 + globals + 64 + 92],%f31
553 ld [%o0 + globals + 64 + 96],%g1
555 ld [%o0 + globals + 64 + 100],%g1
559 ld [%o0 + globals + 168 + 0],%c0 ! Restore floating-point registers
560 ld [%o0 + globals + 168 + 4],%c1
561 ld [%o0 + globals + 168 + 8],%c2
562 ld [%o0 + globals + 168 + 12],%c3
563 ld [%o0 + globals + 168 + 16],%c4
564 ld [%o0 + globals + 168 + 20],%c5
565 ld [%o0 + globals + 168 + 24],%c6
566 ld [%o0 + globals + 168 + 28],%c7
567 ld [%o0 + globals + 200 + 0],%c8
568 ld [%o0 + globals + 200 + 4],%c9
569 ld [%o0 + globals + 200 + 8],%c10
570 ld [%o0 + globals + 200 + 12],%c11
571 ld [%o0 + globals + 200 + 16],%c12
572 ld [%o0 + globals + 200 + 20],%c13
573 ld [%o0 + globals + 200 + 24],%c14
574 ld [%o0 + globals + 200 + 28],%c15
575 ld [%o0 + globals + 200 + 32],%c16
576 ld [%o0 + globals + 200 + 36],%c17
577 ld [%o0 + globals + 200 + 40],%c18
578 ld [%o0 + globals + 200 + 44],%c19
579 ld [%o0 + globals + 200 + 48],%c20
580 ld [%o0 + globals + 200 + 52],%c21
581 ld [%o0 + globals + 200 + 56],%c22
582 ld [%o0 + globals + 200 + 60],%c23
583 ld [%o0 + globals + 200 + 64],%c24
584 ld [%o0 + globals + 200 + 68],%c25
585 ld [%o0 + globals + 200 + 72],%c26
586 ld [%o0 + globals + 200 + 76],%c27
587 ld [%o0 + globals + 200 + 80],%c28
588 ld [%o0 + globals + 200 + 84],%c29
589 ld [%o0 + globals + 200 + 88],%c30
590 ld [%o0 + globals + 200 + 92],%c31
592 ld [%o0 + globals + 200 + 96],%g1
594 ld [%o0 + globals + 200 + 100],%g1
598 ld [%o0 + globals + 28], %g1 ! Restore global regs back
600 ld [%o0 + globals + 0], %g1
601 ld [%o0 + globals + 4], %g2
602 ld [%o0 + globals + 8], %g3
603 ld [%o0 + globals + 12],%g4
604 ld [%o0 + globals + 16],%g5
605 ld [%o0 + globals + 20],%g6
606 ld [%o0 + globals + 24],%g7
608 /* The following 3 lines are equivalent to: _PRE_Block = 0 */
626 | Information Technology Center
627 | Carnegie-Mellon University
643 | Process assembly language assist for Sailboats.
658 | Stuff to allow saving/restoring registers
663 | savecontext(f, area1, newsp)
664 | int (*f)(); struct savearea *area1; char *newsp;
669 ai sp,sp,-regspace | Save frame pointer & ...
670 | ... allocate space for 16 registers
672 stm r0,0(sp) | Change this if save fewer regs.
673 | Set preemption semaphore
676 putc r6,0(r7) | PRE_Block = 1
677 | r3 = base of savearea
678 put sp,topstack(r3) | area1->topstack = sp
681 be L1 | If newsp == 0, no stack switch
682 cas sp,r4,r0 | Switch to new stack
684 get r6,0(r2) | r2 = _f
690 | struct savearea *area2;
696 | Now in the context of the savecontext stack to be restored.
697 | Start with the registers...
698 | Clear preemption semaphore
701 putc r6,0(r7) | PRE_Block = 0
702 lm r0,0(sp) | Change if saving fewer regs.
703 brx r15 | Return to previous process
712 # Information Technology Center
713 # Carnegie-Mellon University
718 # Process assembly language assist for Sailboats.
735 /*# Offsets of fields*/
738 /*# Stuff to allow saving/restoring registers*/
744 # savecontext(f, area1, newsp)
745 # int (*f)(); struct savearea *area1; char *newsp;
750 ai 1,1,-regspace # Save frame pointer & ...
753 stm 0,0(1) # Change this if save fewer regs.
755 /*# Set preemption semaphore*/
759 /*# r3 = base of savearea*/
760 st 1,topstack(3) # area1->topstack = sp
761 /*# New sp is in r4.*/
763 beq L1 # If newsp == 0, no stack switch
764 cas 1,4,0 # Switch to new stack
777 # struct savearea *area2;
787 # Now in the context of the savecontext stack to be restored.
788 # Start with the registers...
789 # Clear preemption semaphore
795 lm 0,0(1) # Change if saving fewer regs.
796 brx 15 # Return to previous process
803 #endif /* AFS_AIX_ENV */
808 # Information Technology Center
809 # Carnegie-Mellon University
817 # Algorithm: "Monkey see, monkey do"
833 /* Stuff to allow saving/restoring registers */
836 # savecontext(f, area1, newsp)
837 # int (*f)(); struct savearea *area1; char *newsp;
840 /* Stack offsets of arguments */
849 .word 0x0ffc # Save regs R2-R11
850 movb $1,_PRE_Block # Critical section for preemption code
851 pushl ap # save old ap
852 pushl fp # save old fp
853 movl area1(ap),r0 # r0 = base of savearea
854 movl sp,topstack(r0) # area->topstack = sp
855 movl newsp(ap),r0 # Get new sp
856 beql L1 # if new sp is 0, dont change stacks
857 movl r0,sp # else switch to new stack
859 movl f(ap),r1 # r1 = f
862 /* It is impossible to be here, so abort() */
868 # struct savearea *area2;
871 /* Stack offset of argument */
876 .word 0x0 # Who cares about these regs?
877 movl area2(ap),r0 # r0 = address of area2
878 movl topstack(r0),sp # Restore sp
879 movl (sp)+,fp # Restore fp
881 clrb _PRE_Block # End of preemption critical section
884 pushl $1234 # The author will gloat
892 #include <regdef.h> /* Allow use of symbolic names for registers. */
893 /* 9 sregs, ra, 6 fp regs, gp, pad to 8 byte boundary */
894 #define regspace 9 * 4 + 4 + 6 * 8 + 4 + 4
896 #define registers floats + 6 * 8
897 #define returnaddr regspace - 4
899 #define GPOFF regspace - 8
900 .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
901 .ent savecontext /* Insert debugger information. */
904 .cpload t9 # set up gp for KPIC
907 .cprestore GPOFF # trigger t9/jalr
913 .frame sp, regspace, ra
914 /* Save registers. */
915 sw s0, registers + 0(sp)
916 sw s1, registers + 4(sp)
917 sw s2, registers + 8(sp)
918 sw s3, registers + 12(sp)
919 sw s4, registers + 16(sp)
920 sw s5, registers + 20(sp)
921 sw s6, registers + 24(sp)
922 sw s7, registers + 28(sp)
923 sw s8, registers + 32(sp)
924 /* Save return address */
925 sw ra, returnaddr(sp)
927 /* Need to save floating point registers? */
928 s.d $f20, floats + 0(sp)
929 s.d $f22, floats + 8(sp)
930 s.d $f24, floats + 16(sp)
931 s.d $f26, floats + 24(sp)
932 s.d $f28, floats + 32(sp)
933 s.d $f30, floats + 40(sp)
934 .fmask 0x55400000, regspace
936 beq a2, $0, samestack
947 .cpload t9 # set up gp for KPIC
951 lw s0, registers + 0(sp)
952 lw s1, registers + 4(sp)
953 lw s2, registers + 8(sp)
954 lw s3, registers + 12(sp)
955 lw s4, registers + 16(sp)
956 lw s5, registers + 20(sp)
957 lw s6, registers + 24(sp)
958 lw s7, registers + 28(sp)
959 lw s8, registers + 32(sp)
960 /* Save return address */
961 lw ra, returnaddr(sp)
962 /* Need to save floating point registers? */
963 l.d $f20, floats + 0(sp)
964 l.d $f22, floats + 8(sp)
965 l.d $f24, floats + 16(sp)
966 l.d $f26, floats + 24(sp)
967 l.d $f28, floats + 32(sp)
968 l.d $f30, floats + 40(sp)
978 /* Code for MIPS R2000/R3000 architecture
979 * Written by Zalman Stern April 30th, 1989.
981 #include <regdef.h> /* Allow use of symbolic names for registers. */
982 #define regspace 9 * 4 + 4 + 6 * 8
984 #define registers floats + 6 * 8
985 #define returnaddr regspace - 4
987 .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
988 .ent savecontext /* Insert debugger information. */
994 .frame sp, regspace, ra
995 /* Save registers. */
996 sw s0, registers + 0(sp)
997 sw s1, registers + 4(sp)
998 sw s2, registers + 8(sp)
999 sw s3, registers + 12(sp)
1000 sw s4, registers + 16(sp)
1001 sw s5, registers + 20(sp)
1002 sw s6, registers + 24(sp)
1003 sw s7, registers + 28(sp)
1004 sw s8, registers + 32(sp)
1005 /* Save return address */
1006 sw ra, returnaddr(sp)
1007 .mask 0xc0ff0000, -4
1008 /* Need to save floating point registers? */
1009 s.d $f20, floats + 0(sp)
1010 s.d $f22, floats + 8(sp)
1011 s.d $f24, floats + 16(sp)
1012 s.d $f26, floats + 24(sp)
1013 s.d $f28, floats + 32(sp)
1014 s.d $f30, floats + 40(sp)
1015 .fmask 0x55400000, regspace
1017 beq a2, $0, samestack
1027 lw s0, registers + 0(sp)
1028 lw s1, registers + 4(sp)
1029 lw s2, registers + 8(sp)
1030 lw s3, registers + 12(sp)
1031 lw s4, registers + 16(sp)
1032 lw s5, registers + 20(sp)
1033 lw s6, registers + 24(sp)
1034 lw s7, registers + 28(sp)
1035 lw s8, registers + 32(sp)
1036 /* Save return address */
1037 lw ra, returnaddr(sp)
1038 /* Need to save floating point registers? */
1039 l.d $f20, floats + 0(sp)
1040 l.d $f22, floats + 8(sp)
1041 l.d $f24, floats + 16(sp)
1042 l.d $f26, floats + 24(sp)
1043 l.d $f28, floats + 32(sp)
1044 l.d $f30, floats + 40(sp)
1053 #include "process.s.hpux"
1054 #endif /* AFS_HPUX_ENV */
1057 /* Code for DEC Alpha architecture */
1059 #include <machine/asm.h>
1060 #include <machine/regdef.h>
1070 #include <mach/alpha/asm.h>
1073 #define FRAMESIZE ((8*8)+8+(7*8))
1075 #define registers (floats+(8*8))
1076 #define returnaddr (FRAMESIZE-8)
1082 NESTED(savecontext,FRAMESIZE,ra)
1084 NESTED(savecontext,3,FRAMESIZE,ra,0x0400f700,0x000003fc)
1089 lda sp,-FRAMESIZE(sp)
1090 /* Save callee-saved registers. */
1091 stq s0, (registers+0) (sp)
1092 stq s1, (registers+8) (sp)
1093 stq s2, (registers+16) (sp)
1094 stq s3, (registers+24) (sp)
1095 stq s4, (registers+32) (sp)
1096 stq s5, (registers+40) (sp)
1097 stq s6, (registers+48) (sp)
1098 /* Save return address */
1099 stq ra, returnaddr(sp)
1101 .mask (M_S0|M_S1|M_S2|M_S3|M_S4|M_S5|M_S6|M_RA), -FRAMESIZE
1103 /* Save floating point registers */
1104 stt fs0, (floats+0) (sp)
1105 stt fs1, (floats+8) (sp)
1106 stt fs2, (floats+16) (sp)
1107 stt fs3, (floats+24) (sp)
1108 stt fs4, (floats+32) (sp)
1109 stt fs5, (floats+40) (sp)
1110 stt fs6, (floats+48) (sp)
1111 stt fs7, (floats+56) (sp)
1114 stq sp, topstack(a1)
1115 or a0,zero,pv /* call point in pv */
1117 or a2,zero,sp /* switch stack */
1119 jsr ra,(pv),0 /* off we go */
1130 ldq sp, topstack(a0)
1131 /* Restore callee-saved regs */
1132 ldq s0, (registers+0) (sp)
1133 ldq s1, (registers+8) (sp)
1134 ldq s2, (registers+16) (sp)
1135 ldq s3, (registers+24) (sp)
1136 ldq s4, (registers+32) (sp)
1137 ldq s5, (registers+40) (sp)
1138 ldq s6, (registers+48) (sp)
1139 /* Return address */
1140 ldq ra, returnaddr(sp)
1141 /* Floating point registers */
1142 ldt fs0, (floats+0) (sp)
1143 ldt fs1, (floats+8) (sp)
1144 ldt fs2, (floats+16) (sp)
1145 ldt fs3, (floats+24) (sp)
1146 ldt fs4, (floats+32) (sp)
1147 ldt fs5, (floats+40) (sp)
1148 ldt fs6, (floats+48) (sp)
1149 ldt fs7, (floats+56) (sp)
1150 lda sp, FRAMESIZE(sp)
1156 #if defined(AFS_NCR_ENV) || defined(AFS_X86_ENV) || defined(AFS_DJGPP_ENV)
1157 /* Sun 386i... I hope this does the right thing!!!
1159 * Written by Derek Atkins <warlord@MIT.EDU>
1160 * (debugging help by Chris Provenzano <proven@mit.edu>)
1163 * "ojala que es correcto!"
1180 * savecontext(f, area1, newsp)
1181 * int (*f)(); struct savearea *area1; char *newsp;
1184 /* offsets, to make my life easier! */
1194 pushl %ebp /* New Frame! */
1196 pusha /* Push all registers */
1197 movl $1,PRE_Block /* Pre-emption code */
1198 movl area1(%ebp),%eax /* eax = base of savearea */
1199 movl %esp,(%eax) /* area->topstack = esp */
1200 movl newsp(%ebp),%eax /* get new sp into eax */
1202 je L1 /* if new sp is 0 then dont change esp */
1203 movl %eax,%esp /* go ahead. make my day! */
1205 jmp *f(%ebp) /* ebx = &f */
1207 /* Shouldnt be here....*/
1213 * struct savearea *area2;
1223 movl %esp, %ebp /* New frame, to get correct pointer */
1224 movl area2(%ebp),%eax /* eax = area2 */
1225 movl (%eax),%esp /* restore esp */
1227 movl $0,PRE_Block /* clear it up... */
1231 /* I see, said the blind man, as he picked up his hammer and saw! */
1236 #endif /* AFS_NCR_ENV */
1239 * 1. Registers R10..R31 and CR0..CR7 are saved
1240 * 2. "struct savearea" must hold at least 3 pointers (long)
1241 * 3. This code will only work on 32 bit machines (601..604), not 620
1242 * 4. No floating point registers are saved
1243 * 5. The save stack "frame" is bigger than absolutely necessary. The
1244 * PowerPC [AIX] ABI needs this extra space.
1248 /* Mach-O assemblers */
1249 #if !defined(NeXT) && !defined(__APPLE__)
1282 #endif /* !NeXT && !__APPLE__ */
1286 * savecontext(int (*f)(), struct savearea *save, char *newsp)
1289 #define FRAME_SIZE (32*4)+(8*4)
1290 #define FRAME_OFFSET (8*4)
1291 #define TOP_OF_STACK (0*4)
1292 #define RETURN (1*4)
1295 #if defined(NeXT) || defined(__APPLE__)
1298 lis r9,ha16(_PRE_Block) /* Disable interrupt fiddling */
1300 stb r8,lo16(_PRE_Block)(r9)
1304 lis r9,PRE_Block@ha /* Disable interrupt fiddling */
1306 stb r8,PRE_Block@l(r9)
1307 #endif /* NeXT || __APPLE__ */
1308 subi r1,r1,FRAME_SIZE
1311 stw r10,10*4+FRAME_OFFSET(r1) /* Save registers */
1312 stw r11,11*4+FRAME_OFFSET(r1)
1313 stw r12,12*4+FRAME_OFFSET(r1)
1314 stw r13,13*4+FRAME_OFFSET(r1)
1315 stw r14,14*4+FRAME_OFFSET(r1)
1316 stw r15,15*4+FRAME_OFFSET(r1)
1317 stw r16,16*4+FRAME_OFFSET(r1)
1318 stw r17,17*4+FRAME_OFFSET(r1)
1319 stw r18,18*4+FRAME_OFFSET(r1)
1320 stw r19,19*4+FRAME_OFFSET(r1)
1321 stw r20,20*4+FRAME_OFFSET(r1)
1322 stw r21,21*4+FRAME_OFFSET(r1)
1323 stw r22,22*4+FRAME_OFFSET(r1)
1324 stw r23,23*4+FRAME_OFFSET(r1)
1325 stw r24,24*4+FRAME_OFFSET(r1)
1326 stw r25,25*4+FRAME_OFFSET(r1)
1327 stw r26,26*4+FRAME_OFFSET(r1)
1328 stw r27,27*4+FRAME_OFFSET(r1)
1329 stw r28,28*4+FRAME_OFFSET(r1)
1330 stw r29,29*4+FRAME_OFFSET(r1)
1331 stw r30,30*4+FRAME_OFFSET(r1)
1332 stw r31,31*4+FRAME_OFFSET(r1)
1333 stw r1,TOP_OF_STACK(r4)
1334 cmpi 0,r5,0 /* New stack specified? */
1338 beq L1 /* No - don't muck with pointer */
1341 L1: blr /* Return */
1344 * returnto(struct savearea *area)
1346 #if defined(NeXT) || defined(__APPLE__)
1352 #endif /* NeXT || __APPLE__ */
1353 lwz r1,TOP_OF_STACK(r3) /* Update stack pointer */
1354 lwz r0,RETURN(r3) /* Get return address */
1358 lwz r10,10*4+FRAME_OFFSET(r1) /* Restore registers */
1359 lwz r11,11*4+FRAME_OFFSET(r1)
1360 lwz r12,12*4+FRAME_OFFSET(r1)
1361 lwz r13,13*4+FRAME_OFFSET(r1)
1362 lwz r14,14*4+FRAME_OFFSET(r1)
1363 lwz r15,15*4+FRAME_OFFSET(r1)
1364 lwz r16,16*4+FRAME_OFFSET(r1)
1365 lwz r17,17*4+FRAME_OFFSET(r1)
1366 lwz r18,18*4+FRAME_OFFSET(r1)
1367 lwz r19,19*4+FRAME_OFFSET(r1)
1368 lwz r20,20*4+FRAME_OFFSET(r1)
1369 lwz r21,21*4+FRAME_OFFSET(r1)
1370 lwz r22,22*4+FRAME_OFFSET(r1)
1371 lwz r23,23*4+FRAME_OFFSET(r1)
1372 lwz r24,24*4+FRAME_OFFSET(r1)
1373 lwz r25,25*4+FRAME_OFFSET(r1)
1374 lwz r26,26*4+FRAME_OFFSET(r1)
1375 lwz r27,27*4+FRAME_OFFSET(r1)
1376 lwz r28,28*4+FRAME_OFFSET(r1)
1377 lwz r29,29*4+FRAME_OFFSET(r1)
1378 lwz r30,30*4+FRAME_OFFSET(r1)
1379 lwz r31,31*4+FRAME_OFFSET(r1)
1380 #if defined(NeXT) || defined(__APPLE__)
1381 lis r9,ha16(_PRE_Block) /* Re-enable interrupt fiddling */
1383 stb r8,lo16(_PRE_Block)(r9)
1385 lis r9,PRE_Block@ha /* Re-enable interrupt fiddling */
1387 stb r8,PRE_Block@l(r9)
1388 #endif /* NeXT || __APPLE__ */
1389 addi r1,r1,FRAME_SIZE