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 /*#ifndef AFS_DJGPP_ENV*/
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>
353 #include <machine/trap.h>
354 #define ST_FLUSH_WINDOWS ST_FLUSHWIN
356 #define SA(x) (((x)+7)&~7)
357 #define STACK_ALIGN 8
359 #include <sun4/asm_linkage.h>
360 #include <sun4/trap.h>
372 # savecontext(f, area1, newsp)
373 # int (*f)(); struct savearea *area1; char *newsp;
383 save %sp, -SA(MINFRAME), %sp ! Get new window
384 ta ST_FLUSH_WINDOWS ! FLush all other active windows
386 /* The following 3 lines do the equivalent of: _PRE_Block = 1 */
395 st %fp,[%i1+topstack] ! area1->topstack = sp
397 st %g1, [%i1 + globals + 0] /* Save all globals just in case */
398 st %g2, [%i1 + globals + 4]
399 st %g3, [%i1 + globals + 8]
400 st %g4, [%i1 + globals + 12]
401 st %g5, [%i1 + globals + 16]
402 st %g6, [%i1 + globals + 20]
403 st %g7, [%i1 + globals + 24]
405 st %g1, [%i1 + globals + 28]
408 st %f0, [%i1 + globals + 32 + 0] ! Save all floating point registers
409 st %f1, [%i1 + globals + 32 + 4]
410 st %f2, [%i1 + globals + 32 + 8]
411 st %f3, [%i1 + globals + 32 + 12]
412 st %f4, [%i1 + globals + 32 + 16]
413 st %f5, [%i1 + globals + 32 + 20]
414 st %f6, [%i1 + globals + 32 + 24]
415 st %f7, [%i1 + globals + 32 + 28]
416 st %f8, [%i1 + globals + 64 + 0]
417 st %f9, [%i1 + globals + 64 + 4]
418 st %f10, [%i1 + globals + 64 + 8]
419 st %f11, [%i1 + globals + 64 + 12]
420 st %f12, [%i1 + globals + 64 + 16]
421 st %f13, [%i1 + globals + 64 + 20]
422 st %f14, [%i1 + globals + 64 + 24]
423 st %f15, [%i1 + globals + 64 + 28]
424 st %f16, [%i1 + globals + 64 + 32]
425 st %f17, [%i1 + globals + 64 + 36]
426 st %f18, [%i1 + globals + 64 + 40]
427 st %f19, [%i1 + globals + 64 + 44]
428 st %f20, [%i1 + globals + 64 + 48]
429 st %f21, [%i1 + globals + 64 + 52]
430 st %f22, [%i1 + globals + 64 + 56]
431 st %f23, [%i1 + globals + 64 + 60]
432 st %f24, [%i1 + globals + 64 + 64]
433 st %f25, [%i1 + globals + 64 + 68]
434 st %f26, [%i1 + globals + 64 + 72]
435 st %f27, [%i1 + globals + 64 + 76]
436 st %f28, [%i1 + globals + 64 + 80]
437 st %f29, [%i1 + globals + 64 + 84]
438 st %f30, [%i1 + globals + 64 + 88]
439 st %f31, [%i1 + globals + 64 + 92]
442 st %g1, [%i1 + globals + 64 + 96]
444 st %g1, [%i1 + globals + 64 + 100]
447 st %c0, [%i1 + globals + 168 + 0] ! Save all coprocessor registers
448 st %c1, [%i1 + globals + 168 + 4]
449 st %c2, [%i1 + globals + 168 + 8]
450 st %c3, [%i1 + globals + 168 + 12]
451 st %c4, [%i1 + globals + 168 + 16]
452 st %c5, [%i1 + globals + 168 + 20]
453 st %c6, [%i1 + globals + 168 + 24]
454 st %c7, [%i1 + globals + 168 + 28]
455 st %c8, [%i1 + globals + 200 + 0]
456 st %c9, [%i1 + globals + 200 + 4]
457 st %c10, [%i1 + globals + 200 + 8]
458 st %c11, [%i1 + globals + 200 + 12]
459 st %c12, [%i1 + globals + 200 + 16]
460 st %c13, [%i1 + globals + 200 + 20]
461 st %c14, [%i1 + globals + 200 + 24]
462 st %c15, [%i1 + globals + 200 + 28]
463 st %c16, [%i1 + globals + 200 + 32]
464 st %c17, [%i1 + globals + 200 + 36]
465 st %c18, [%i1 + globals + 200 + 40]
466 st %c19, [%i1 + globals + 200 + 44]
467 st %c20, [%i1 + globals + 200 + 48]
468 st %c21, [%i1 + globals + 200 + 52]
469 st %c22, [%i1 + globals + 200 + 56]
470 st %c23, [%i1 + globals + 200 + 60]
471 st %c24, [%i1 + globals + 200 + 64]
472 st %c25, [%i1 + globals + 200 + 68]
473 st %c26, [%i1 + globals + 200 + 72]
474 st %c27, [%i1 + globals + 200 + 76]
475 st %c28, [%i1 + globals + 200 + 80]
476 st %c29, [%i1 + globals + 200 + 84]
477 st %c30, [%i1 + globals + 200 + 88]
478 st %c31, [%i1 + globals + 200 + 92]
481 st %g1, [%i1 + globals + 200 + 96]
483 st %g1, [%i1 + globals + 200 + 100]
487 be,a L1 ! if (newsp == 0) no stack switch
490 add %i2, STACK_ALIGN - 1, %i2
491 and %i2, ~(STACK_ALIGN - 1), %i2
492 sub %i2, SA(MINFRAME), %fp
496 ! This used to compute a new stack frame base, write it into
497 ! FP, and restore to enter the new frame. But that left a window
498 ! in which FP could be written into the backing store for this
499 ! frame, to be tripped over later by returnto. So instead we do
500 ! the restore first, then modify SP to enter the new frame. We
501 ! can still refer to our argument as %02.
503 add %o2, STACK_ALIGN - 1, %o2
504 and %o2, ~(STACK_ALIGN - 1), %o2
506 sub %o2, SA(MINFRAME), %sp
509 L1: call %i0 ! call f()
514 ! struct savearea *area1;
522 ta ST_FLUSH_WINDOWS ! FLush all other active windows
523 ld [%o0+topstack],%g1 ! sp = area1->topstack
524 sub %g1, SA(MINFRAME), %fp ! Adjust sp to the right place
525 sub %fp, SA(MINFRAME), %sp
528 ld [%o0 + globals + 32 + 0],%f0 ! Restore floating-point registers
529 ld [%o0 + globals + 32 + 4],%f1
530 ld [%o0 + globals + 32 + 8],%f2
531 ld [%o0 + globals + 32 + 12],%f3
532 ld [%o0 + globals + 32 + 16],%f4
533 ld [%o0 + globals + 32 + 20],%f5
534 ld [%o0 + globals + 32 + 24],%f6
535 ld [%o0 + globals + 32 + 28],%f7
536 ld [%o0 + globals + 64 + 0],%f8
537 ld [%o0 + globals + 64 + 4],%f9
538 ld [%o0 + globals + 64 + 8],%f10
539 ld [%o0 + globals + 64 + 12],%f11
540 ld [%o0 + globals + 64 + 16],%f12
541 ld [%o0 + globals + 64 + 20],%f13
542 ld [%o0 + globals + 64 + 24],%f14
543 ld [%o0 + globals + 64 + 28],%f15
544 ld [%o0 + globals + 64 + 32],%f16
545 ld [%o0 + globals + 64 + 36],%f17
546 ld [%o0 + globals + 64 + 40],%f18
547 ld [%o0 + globals + 64 + 44],%f19
548 ld [%o0 + globals + 64 + 48],%f20
549 ld [%o0 + globals + 64 + 52],%f21
550 ld [%o0 + globals + 64 + 56],%f22
551 ld [%o0 + globals + 64 + 60],%f23
552 ld [%o0 + globals + 64 + 64],%f24
553 ld [%o0 + globals + 64 + 68],%f25
554 ld [%o0 + globals + 64 + 72],%f26
555 ld [%o0 + globals + 64 + 76],%f27
556 ld [%o0 + globals + 64 + 80],%f28
557 ld [%o0 + globals + 64 + 84],%f29
558 ld [%o0 + globals + 64 + 88],%f30
559 ld [%o0 + globals + 64 + 92],%f31
561 ld [%o0 + globals + 64 + 96],%g1
563 ld [%o0 + globals + 64 + 100],%g1
567 ld [%o0 + globals + 168 + 0],%c0 ! Restore floating-point registers
568 ld [%o0 + globals + 168 + 4],%c1
569 ld [%o0 + globals + 168 + 8],%c2
570 ld [%o0 + globals + 168 + 12],%c3
571 ld [%o0 + globals + 168 + 16],%c4
572 ld [%o0 + globals + 168 + 20],%c5
573 ld [%o0 + globals + 168 + 24],%c6
574 ld [%o0 + globals + 168 + 28],%c7
575 ld [%o0 + globals + 200 + 0],%c8
576 ld [%o0 + globals + 200 + 4],%c9
577 ld [%o0 + globals + 200 + 8],%c10
578 ld [%o0 + globals + 200 + 12],%c11
579 ld [%o0 + globals + 200 + 16],%c12
580 ld [%o0 + globals + 200 + 20],%c13
581 ld [%o0 + globals + 200 + 24],%c14
582 ld [%o0 + globals + 200 + 28],%c15
583 ld [%o0 + globals + 200 + 32],%c16
584 ld [%o0 + globals + 200 + 36],%c17
585 ld [%o0 + globals + 200 + 40],%c18
586 ld [%o0 + globals + 200 + 44],%c19
587 ld [%o0 + globals + 200 + 48],%c20
588 ld [%o0 + globals + 200 + 52],%c21
589 ld [%o0 + globals + 200 + 56],%c22
590 ld [%o0 + globals + 200 + 60],%c23
591 ld [%o0 + globals + 200 + 64],%c24
592 ld [%o0 + globals + 200 + 68],%c25
593 ld [%o0 + globals + 200 + 72],%c26
594 ld [%o0 + globals + 200 + 76],%c27
595 ld [%o0 + globals + 200 + 80],%c28
596 ld [%o0 + globals + 200 + 84],%c29
597 ld [%o0 + globals + 200 + 88],%c30
598 ld [%o0 + globals + 200 + 92],%c31
600 ld [%o0 + globals + 200 + 96],%g1
602 ld [%o0 + globals + 200 + 100],%g1
606 ld [%o0 + globals + 28], %g1 ! Restore global regs back
608 ld [%o0 + globals + 0], %g1
609 ld [%o0 + globals + 4], %g2
610 ld [%o0 + globals + 8], %g3
611 ld [%o0 + globals + 12],%g4
612 ld [%o0 + globals + 16],%g5
613 ld [%o0 + globals + 20],%g6
614 ld [%o0 + globals + 24],%g7
616 /* The following 3 lines are equivalent to: _PRE_Block = 0 */
634 | Information Technology Center
635 | Carnegie-Mellon University
651 | Process assembly language assist for Sailboats.
666 | Stuff to allow saving/restoring registers
671 | savecontext(f, area1, newsp)
672 | int (*f)(); struct savearea *area1; char *newsp;
677 ai sp,sp,-regspace | Save frame pointer & ...
678 | ... allocate space for 16 registers
680 stm r0,0(sp) | Change this if save fewer regs.
681 | Set preemption semaphore
684 putc r6,0(r7) | PRE_Block = 1
685 | r3 = base of savearea
686 put sp,topstack(r3) | area1->topstack = sp
689 be L1 | If newsp == 0, no stack switch
690 cas sp,r4,r0 | Switch to new stack
692 get r6,0(r2) | r2 = _f
698 | struct savearea *area2;
704 | Now in the context of the savecontext stack to be restored.
705 | Start with the registers...
706 | Clear preemption semaphore
709 putc r6,0(r7) | PRE_Block = 0
710 lm r0,0(sp) | Change if saving fewer regs.
711 brx r15 | Return to previous process
720 # Information Technology Center
721 # Carnegie-Mellon University
726 # Process assembly language assist for Sailboats.
743 /*# Offsets of fields*/
746 /*# Stuff to allow saving/restoring registers*/
752 # savecontext(f, area1, newsp)
753 # int (*f)(); struct savearea *area1; char *newsp;
758 ai 1,1,-regspace # Save frame pointer & ...
761 stm 0,0(1) # Change this if save fewer regs.
763 /*# Set preemption semaphore*/
767 /*# r3 = base of savearea*/
768 st 1,topstack(3) # area1->topstack = sp
769 /*# New sp is in r4.*/
771 beq L1 # If newsp == 0, no stack switch
772 cas 1,4,0 # Switch to new stack
785 # struct savearea *area2;
795 # Now in the context of the savecontext stack to be restored.
796 # Start with the registers...
797 # Clear preemption semaphore
803 lm 0,0(1) # Change if saving fewer regs.
804 brx 15 # Return to previous process
811 #endif /* AFS_AIX_ENV */
816 # Information Technology Center
817 # Carnegie-Mellon University
825 # Algorithm: "Monkey see, monkey do"
841 /* Stuff to allow saving/restoring registers */
844 # savecontext(f, area1, newsp)
845 # int (*f)(); struct savearea *area1; char *newsp;
848 /* Stack offsets of arguments */
857 .word 0x0ffc # Save regs R2-R11
858 movb $1,_PRE_Block # Critical section for preemption code
859 pushl ap # save old ap
860 pushl fp # save old fp
861 movl area1(ap),r0 # r0 = base of savearea
862 movl sp,topstack(r0) # area->topstack = sp
863 movl newsp(ap),r0 # Get new sp
864 beql L1 # if new sp is 0, dont change stacks
865 movl r0,sp # else switch to new stack
867 movl f(ap),r1 # r1 = f
870 /* It is impossible to be here, so abort() */
876 # struct savearea *area2;
879 /* Stack offset of argument */
884 .word 0x0 # Who cares about these regs?
885 movl area2(ap),r0 # r0 = address of area2
886 movl topstack(r0),sp # Restore sp
887 movl (sp)+,fp # Restore fp
889 clrb _PRE_Block # End of preemption critical section
892 pushl $1234 # The author will gloat
900 #include <regdef.h> /* Allow use of symbolic names for registers. */
901 /* 9 sregs, ra, 6 fp regs, gp, pad to 8 byte boundary */
902 #define regspace 9 * 4 + 4 + 6 * 8 + 4 + 4
904 #define registers floats + 6 * 8
905 #define returnaddr regspace - 4
907 #define GPOFF regspace - 8
908 .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
909 .ent savecontext /* Insert debugger information. */
912 .cpload t9 # set up gp for KPIC
915 .cprestore GPOFF # trigger t9/jalr
921 .frame sp, regspace, ra
922 /* Save registers. */
923 sw s0, registers + 0(sp)
924 sw s1, registers + 4(sp)
925 sw s2, registers + 8(sp)
926 sw s3, registers + 12(sp)
927 sw s4, registers + 16(sp)
928 sw s5, registers + 20(sp)
929 sw s6, registers + 24(sp)
930 sw s7, registers + 28(sp)
931 sw s8, registers + 32(sp)
932 /* Save return address */
933 sw ra, returnaddr(sp)
935 /* Need to save floating point registers? */
936 s.d $f20, floats + 0(sp)
937 s.d $f22, floats + 8(sp)
938 s.d $f24, floats + 16(sp)
939 s.d $f26, floats + 24(sp)
940 s.d $f28, floats + 32(sp)
941 s.d $f30, floats + 40(sp)
942 .fmask 0x55400000, regspace
944 beq a2, $0, samestack
955 .cpload t9 # set up gp for KPIC
959 lw s0, registers + 0(sp)
960 lw s1, registers + 4(sp)
961 lw s2, registers + 8(sp)
962 lw s3, registers + 12(sp)
963 lw s4, registers + 16(sp)
964 lw s5, registers + 20(sp)
965 lw s6, registers + 24(sp)
966 lw s7, registers + 28(sp)
967 lw s8, registers + 32(sp)
968 /* Save return address */
969 lw ra, returnaddr(sp)
970 /* Need to save floating point registers? */
971 l.d $f20, floats + 0(sp)
972 l.d $f22, floats + 8(sp)
973 l.d $f24, floats + 16(sp)
974 l.d $f26, floats + 24(sp)
975 l.d $f28, floats + 32(sp)
976 l.d $f30, floats + 40(sp)
986 /* Code for MIPS R2000/R3000 architecture
987 * Written by Zalman Stern April 30th, 1989.
989 #include <regdef.h> /* Allow use of symbolic names for registers. */
990 #define regspace 9 * 4 + 4 + 6 * 8
992 #define registers floats + 6 * 8
993 #define returnaddr regspace - 4
995 .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
996 .ent savecontext /* Insert debugger information. */
1002 .frame sp, regspace, ra
1003 /* Save registers. */
1004 sw s0, registers + 0(sp)
1005 sw s1, registers + 4(sp)
1006 sw s2, registers + 8(sp)
1007 sw s3, registers + 12(sp)
1008 sw s4, registers + 16(sp)
1009 sw s5, registers + 20(sp)
1010 sw s6, registers + 24(sp)
1011 sw s7, registers + 28(sp)
1012 sw s8, registers + 32(sp)
1013 /* Save return address */
1014 sw ra, returnaddr(sp)
1015 .mask 0xc0ff0000, -4
1016 /* Need to save floating point registers? */
1017 s.d $f20, floats + 0(sp)
1018 s.d $f22, floats + 8(sp)
1019 s.d $f24, floats + 16(sp)
1020 s.d $f26, floats + 24(sp)
1021 s.d $f28, floats + 32(sp)
1022 s.d $f30, floats + 40(sp)
1023 .fmask 0x55400000, regspace
1025 beq a2, $0, samestack
1035 lw s0, registers + 0(sp)
1036 lw s1, registers + 4(sp)
1037 lw s2, registers + 8(sp)
1038 lw s3, registers + 12(sp)
1039 lw s4, registers + 16(sp)
1040 lw s5, registers + 20(sp)
1041 lw s6, registers + 24(sp)
1042 lw s7, registers + 28(sp)
1043 lw s8, registers + 32(sp)
1044 /* Save return address */
1045 lw ra, returnaddr(sp)
1046 /* Need to save floating point registers? */
1047 l.d $f20, floats + 0(sp)
1048 l.d $f22, floats + 8(sp)
1049 l.d $f24, floats + 16(sp)
1050 l.d $f26, floats + 24(sp)
1051 l.d $f28, floats + 32(sp)
1052 l.d $f30, floats + 40(sp)
1061 #include "process.s.hpux"
1062 #endif /* AFS_HPUX_ENV */
1065 /* Code for DEC Alpha architecture */
1067 #include <machine/asm.h>
1068 #include <machine/regdef.h>
1077 #elif defined(AFS_XBSD_ENV)
1078 #include <machine/asm.h>
1079 #else /* !OSF && !XBSD */
1080 #include <mach/alpha/asm.h>
1083 #define FRAMESIZE ((8*8)+8+(7*8))
1085 #define registers (floats+(8*8))
1086 #define returnaddr (FRAMESIZE-8)
1094 NESTED(savecontext,FRAMESIZE,ra)
1096 NESTED(savecontext,3,FRAMESIZE,ra,0x0400f700,0x000003fc)
1101 lda sp,-FRAMESIZE(sp)
1102 /* Save callee-saved registers. */
1103 stq s0, (registers+0) (sp)
1104 stq s1, (registers+8) (sp)
1105 stq s2, (registers+16) (sp)
1106 stq s3, (registers+24) (sp)
1107 stq s4, (registers+32) (sp)
1108 stq s5, (registers+40) (sp)
1109 stq s6, (registers+48) (sp)
1110 /* Save return address */
1111 stq ra, returnaddr(sp)
1113 .mask (M_S0|M_S1|M_S2|M_S3|M_S4|M_S5|M_S6|M_RA), -FRAMESIZE
1115 /* Save floating point registers */
1116 stt fs0, (floats+0) (sp)
1117 stt fs1, (floats+8) (sp)
1118 stt fs2, (floats+16) (sp)
1119 stt fs3, (floats+24) (sp)
1120 stt fs4, (floats+32) (sp)
1121 stt fs5, (floats+40) (sp)
1122 stt fs6, (floats+48) (sp)
1123 stt fs7, (floats+56) (sp)
1126 stq sp, topstack(a1)
1127 or a0,zero,pv /* call point in pv */
1129 or a2,zero,sp /* switch stack */
1131 jsr ra,(pv),0 /* off we go */
1142 ldq sp, topstack(a0)
1143 /* Restore callee-saved regs */
1144 ldq s0, (registers+0) (sp)
1145 ldq s1, (registers+8) (sp)
1146 ldq s2, (registers+16) (sp)
1147 ldq s3, (registers+24) (sp)
1148 ldq s4, (registers+32) (sp)
1149 ldq s5, (registers+40) (sp)
1150 ldq s6, (registers+48) (sp)
1151 /* Return address */
1152 ldq ra, returnaddr(sp)
1153 /* Floating point registers */
1154 ldt fs0, (floats+0) (sp)
1155 ldt fs1, (floats+8) (sp)
1156 ldt fs2, (floats+16) (sp)
1157 ldt fs3, (floats+24) (sp)
1158 ldt fs4, (floats+32) (sp)
1159 ldt fs5, (floats+40) (sp)
1160 ldt fs6, (floats+48) (sp)
1161 ldt fs7, (floats+56) (sp)
1162 lda sp, FRAMESIZE(sp)
1170 * 1. Registers R10..R31 and CR0..CR7 are saved
1171 * 2. "struct savearea" must hold at least 3 pointers (long)
1172 * 3. This code will only work on 32 bit machines (601..604), not 620
1173 * 4. No floating point registers are saved
1174 * 5. The save stack "frame" is bigger than absolutely necessary. The
1175 * PowerPC [AIX] ABI needs this extra space.
1179 /* Mach-O assemblers */
1180 #if !defined(NeXT) && !defined(__APPLE__)
1213 #endif /* !NeXT && !__APPLE__ */
1217 * savecontext(int (*f)(), struct savearea *save, char *newsp)
1220 #define FRAME_SIZE (32*4)+(8*4)
1221 #define FRAME_OFFSET (8*4)
1222 #define TOP_OF_STACK (0*4)
1223 #define RETURN (1*4)
1226 #if defined(NeXT) || defined(__APPLE__)
1229 lis r9,ha16(_PRE_Block) /* Disable interrupt fiddling */
1231 stb r8,lo16(_PRE_Block)(r9)
1235 lis r9,PRE_Block@ha /* Disable interrupt fiddling */
1237 stb r8,PRE_Block@l(r9)
1238 #endif /* NeXT || __APPLE__ */
1239 subi r1,r1,FRAME_SIZE
1242 stw r10,10*4+FRAME_OFFSET(r1) /* Save registers */
1243 stw r11,11*4+FRAME_OFFSET(r1)
1244 stw r12,12*4+FRAME_OFFSET(r1)
1245 stw r13,13*4+FRAME_OFFSET(r1)
1246 stw r14,14*4+FRAME_OFFSET(r1)
1247 stw r15,15*4+FRAME_OFFSET(r1)
1248 stw r16,16*4+FRAME_OFFSET(r1)
1249 stw r17,17*4+FRAME_OFFSET(r1)
1250 stw r18,18*4+FRAME_OFFSET(r1)
1251 stw r19,19*4+FRAME_OFFSET(r1)
1252 stw r20,20*4+FRAME_OFFSET(r1)
1253 stw r21,21*4+FRAME_OFFSET(r1)
1254 stw r22,22*4+FRAME_OFFSET(r1)
1255 stw r23,23*4+FRAME_OFFSET(r1)
1256 stw r24,24*4+FRAME_OFFSET(r1)
1257 stw r25,25*4+FRAME_OFFSET(r1)
1258 stw r26,26*4+FRAME_OFFSET(r1)
1259 stw r27,27*4+FRAME_OFFSET(r1)
1260 stw r28,28*4+FRAME_OFFSET(r1)
1261 stw r29,29*4+FRAME_OFFSET(r1)
1262 stw r30,30*4+FRAME_OFFSET(r1)
1263 stw r31,31*4+FRAME_OFFSET(r1)
1264 stw r1,TOP_OF_STACK(r4)
1265 cmpi 0,r5,0 /* New stack specified? */
1269 beq L1 /* No - don't muck with pointer */
1272 L1: blr /* Return */
1275 * returnto(struct savearea *area)
1277 #if defined(NeXT) || defined(__APPLE__)
1283 #endif /* NeXT || __APPLE__ */
1284 lwz r1,TOP_OF_STACK(r3) /* Update stack pointer */
1285 lwz r0,RETURN(r3) /* Get return address */
1289 lwz r10,10*4+FRAME_OFFSET(r1) /* Restore registers */
1290 lwz r11,11*4+FRAME_OFFSET(r1)
1291 lwz r12,12*4+FRAME_OFFSET(r1)
1292 lwz r13,13*4+FRAME_OFFSET(r1)
1293 lwz r14,14*4+FRAME_OFFSET(r1)
1294 lwz r15,15*4+FRAME_OFFSET(r1)
1295 lwz r16,16*4+FRAME_OFFSET(r1)
1296 lwz r17,17*4+FRAME_OFFSET(r1)
1297 lwz r18,18*4+FRAME_OFFSET(r1)
1298 lwz r19,19*4+FRAME_OFFSET(r1)
1299 lwz r20,20*4+FRAME_OFFSET(r1)
1300 lwz r21,21*4+FRAME_OFFSET(r1)
1301 lwz r22,22*4+FRAME_OFFSET(r1)
1302 lwz r23,23*4+FRAME_OFFSET(r1)
1303 lwz r24,24*4+FRAME_OFFSET(r1)
1304 lwz r25,25*4+FRAME_OFFSET(r1)
1305 lwz r26,26*4+FRAME_OFFSET(r1)
1306 lwz r27,27*4+FRAME_OFFSET(r1)
1307 lwz r28,28*4+FRAME_OFFSET(r1)
1308 lwz r29,29*4+FRAME_OFFSET(r1)
1309 lwz r30,30*4+FRAME_OFFSET(r1)
1310 lwz r31,31*4+FRAME_OFFSET(r1)
1311 #if defined(NeXT) || defined(__APPLE__)
1312 lis r9,ha16(_PRE_Block) /* Re-enable interrupt fiddling */
1314 stb r8,lo16(_PRE_Block)(r9)
1316 lis r9,PRE_Block@ha /* Re-enable interrupt fiddling */
1318 stb r8,PRE_Block@l(r9)
1319 #endif /* NeXT || __APPLE__ */
1320 addi r1,r1,FRAME_SIZE