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>
15 /* I don't know if we have to save the TOC (R2) or not...
16 * Note that stack-frame is supposed to be aligned on
17 * a double-word boundary.
18 * For details about RIOS calling conventions
19 * see the Assembler manual and /usr/include/sys/asdef.s
24 * savecontext(f, area1, newsp)
25 * int (*f)(); struct savearea *area1; char *newsp;
47 .set szdsa, 8*nfprs+4*ngprs+linkarea+argarea
49 .csect .savecontext[PR]
50 .globl .savecontext[PR]
52 mflr r0 # save link register
55 * save floating point registers. Interleave some other stuff for
56 * timing reasons. Set up conditions and registers for branches
57 * early, so that processor can prefetch instructions.
67 l 11, 0(a_f) # r11 <- *(a_f)
72 cmpi cr0, a_newsp, 0 # cr0 <- (a_newsp :: 0)
78 mtlr 11 # set up lr early so prefetch works
84 st r0, 8(r1) # save return addr
90 st 12, 4(r1) # save CR
97 * save general-purpose registers
99 stm 12, -8*nfprs-4*ngprs(r1)# save the general-purpose regs
100 stu r1, -szdsa(r1) # dec SP and save back chain
102 l r7, PRE_Block.S(toc) # r7 <- &PRE_Block
103 cal r6, 1(r0) # r6 <- #1
104 stb r6, 0(r7) # r6 -> PRE_Block
106 st r1, topstack(a_area1) # save old SP
108 beq L1 # if (a_newsp == 0) goto L1
110 mr r1, r5 # r1 <- a_newsp -- load new SP
112 L1: brl # pc <- lr -- (*a_f)()
115 * returnto(area2) This is a little jumbled, I tried to interleave
116 * memory accesses with simple instructions for speed, and I tried to
117 * set up the link register and condition register reasonably early
118 * so that processor instruction prefetching might help us out a little.
125 l r1, topstack(a_area2) # r1 <- a_area2->topstack
126 cal r1, szdsa(r1) # pop off frame
127 l r7, PRE_Block.S(toc) # r7 <- &PRE_Block
129 l 8, 8(1) # restore lr
130 mtlr 8 # do it early so prefetch works
132 lm 12, -8*nfprs-4*ngprs(r1)
133 cal r6, 0(r0) # r6 <- #0
134 mtcrf 0x38, 12 # put back cr
135 stb r6, 0(r7) # r6 -> PRE_Block
159 brl # pc <- lr -- return
164 .tc PRE_Block[tc], PRE_Block[ua]
165 .extern PRE_Block[ua]
168 #if defined(AFS_S390_LINUX20_ENV)
169 /* Linux for S/390 (31 bit)
171 * Written by Neale Ferguson <Neale.Ferguson@SoftwareAG-usa.com>
173 * additional munging by Adam Thornton <adam@sinenomine.net>
178 .type savecontext,%function
180 * savecontext(f, area1, newsp)
181 * int (*f)(); struct savearea *area1; char *newsp;
193 P_PRE: .long PRE_Block
197 stm %r6,%r15,24(%r15) /* Save our registers */
199 ahi %r15,-96 /* Move out of harm's way */
201 bras %r5,.L0 /* Get A(A(PRE_Block)) */
204 l %r5,0(%r5) /* Get A(PRE_Block) */
205 mvi 0(%r5),1 /* Set it */
206 lr %r6,%r3 /* Get base of savearea */
207 st %r15,0(%r3) /* Save stack pointer */
208 ltr %r4,%r4 /* If new sp is 0 */
209 jz .L1 /* ... don't change sp */
210 lr %r15,%r4 /* Set new stack pointer */
212 br %r2 /* Call the routine */
213 /* Can't get here....*/
222 .size savecontext,.savecontext_end-savecontext
226 * struct savearea *area2;
231 .type returnto,%function
233 l %r15,0(%r2) /* New frame, to get correct pointer*/
234 bras %r5,.L3 /* Get A(A(PRE_Block))
238 l %r5,0(%r5) /* Get A(PRE_Block) */
239 xc 0(4,%r5),0(%r5) /* Clear it */
241 lm %r6,%r15,24(%r15) /* Restore registers */
252 .size returnto,.returnto_end-returnto
253 #endif /* AFS_S390_LINUX20_ENV */
258 # Information Technology Center
259 # Carnegie-Mellon University
267 # Process assembly language assist for Suns.
286 /* Stuff to allow saving/restoring registers */
288 regs = 0x3ffe | d1-d7 & a0-a5
291 # savecontext(f, area1, newsp)
292 # int (*f)(); struct savearea *area1; char *newsp;
295 /* Stack offsets of arguments */
302 movb #1,_PRE_Block | Dont allow any interrupt finagling
303 link a6,#-(nregs*4) | Save frame pointer & ...
304 | ... allocate space for nregs registers
308 movl a6@(area1),a0 | a0 = base of savearea
309 movl sp,a0@(topstack) | area->topstack = sp
310 movl a6@(newsp),d0 | Get new sp
311 jeq forw1 | If newsp == 0, no stack switch
312 movl d0,sp | Switch to new stack
314 movl a6@(f),a0 | a0 = f
317 /* It is impossible to be here, so abort() */
323 # struct savearea *area2;
326 /* Stack offset of argument */
332 movl a6@(area2),a0 | Base of savearea
333 movl a0@(topstack),sp | Restore sp
334 /* Restore registers */
338 movl sp,a6 | Argghh...be careful here
341 rts | Return to previous process
346 #include <sys/asm_linkage.h>
347 #include <sys/trap.h>
349 #include <sun4/asm_linkage.h>
350 #include <sun4/trap.h>
361 # savecontext(f, area1, newsp)
362 # int (*f)(); struct savearea *area1; char *newsp;
372 save %sp, -SA(MINFRAME), %sp ! Get new window
373 ta ST_FLUSH_WINDOWS ! FLush all other active windows
375 /* The following 3 lines do the equivalent of: _PRE_Block = 1 */
384 st %fp,[%i1+topstack] ! area1->topstack = sp
386 st %g1, [%i1 + globals + 0] /* Save all globals just in case */
387 st %g2, [%i1 + globals + 4]
388 st %g3, [%i1 + globals + 8]
389 st %g4, [%i1 + globals + 12]
390 st %g5, [%i1 + globals + 16]
391 st %g6, [%i1 + globals + 20]
392 st %g7, [%i1 + globals + 24]
394 st %g1, [%i1 + globals + 28]
397 st %f0, [%i1 + globals + 32 + 0] ! Save all floating point registers
398 st %f1, [%i1 + globals + 32 + 4]
399 st %f2, [%i1 + globals + 32 + 8]
400 st %f3, [%i1 + globals + 32 + 12]
401 st %f4, [%i1 + globals + 32 + 16]
402 st %f5, [%i1 + globals + 32 + 20]
403 st %f6, [%i1 + globals + 32 + 24]
404 st %f7, [%i1 + globals + 32 + 28]
405 st %f8, [%i1 + globals + 64 + 0]
406 st %f9, [%i1 + globals + 64 + 4]
407 st %f10, [%i1 + globals + 64 + 8]
408 st %f11, [%i1 + globals + 64 + 12]
409 st %f12, [%i1 + globals + 64 + 16]
410 st %f13, [%i1 + globals + 64 + 20]
411 st %f14, [%i1 + globals + 64 + 24]
412 st %f15, [%i1 + globals + 64 + 28]
413 st %f16, [%i1 + globals + 64 + 32]
414 st %f17, [%i1 + globals + 64 + 36]
415 st %f18, [%i1 + globals + 64 + 40]
416 st %f19, [%i1 + globals + 64 + 44]
417 st %f20, [%i1 + globals + 64 + 48]
418 st %f21, [%i1 + globals + 64 + 52]
419 st %f22, [%i1 + globals + 64 + 56]
420 st %f23, [%i1 + globals + 64 + 60]
421 st %f24, [%i1 + globals + 64 + 64]
422 st %f25, [%i1 + globals + 64 + 68]
423 st %f26, [%i1 + globals + 64 + 72]
424 st %f27, [%i1 + globals + 64 + 76]
425 st %f28, [%i1 + globals + 64 + 80]
426 st %f29, [%i1 + globals + 64 + 84]
427 st %f30, [%i1 + globals + 64 + 88]
428 st %f31, [%i1 + globals + 64 + 92]
431 st %g1, [%i1 + globals + 64 + 96]
433 st %g1, [%i1 + globals + 64 + 100]
436 st %c0, [%i1 + globals + 168 + 0] ! Save all coprocessor registers
437 st %c1, [%i1 + globals + 168 + 4]
438 st %c2, [%i1 + globals + 168 + 8]
439 st %c3, [%i1 + globals + 168 + 12]
440 st %c4, [%i1 + globals + 168 + 16]
441 st %c5, [%i1 + globals + 168 + 20]
442 st %c6, [%i1 + globals + 168 + 24]
443 st %c7, [%i1 + globals + 168 + 28]
444 st %c8, [%i1 + globals + 200 + 0]
445 st %c9, [%i1 + globals + 200 + 4]
446 st %c10, [%i1 + globals + 200 + 8]
447 st %c11, [%i1 + globals + 200 + 12]
448 st %c12, [%i1 + globals + 200 + 16]
449 st %c13, [%i1 + globals + 200 + 20]
450 st %c14, [%i1 + globals + 200 + 24]
451 st %c15, [%i1 + globals + 200 + 28]
452 st %c16, [%i1 + globals + 200 + 32]
453 st %c17, [%i1 + globals + 200 + 36]
454 st %c18, [%i1 + globals + 200 + 40]
455 st %c19, [%i1 + globals + 200 + 44]
456 st %c20, [%i1 + globals + 200 + 48]
457 st %c21, [%i1 + globals + 200 + 52]
458 st %c22, [%i1 + globals + 200 + 56]
459 st %c23, [%i1 + globals + 200 + 60]
460 st %c24, [%i1 + globals + 200 + 64]
461 st %c25, [%i1 + globals + 200 + 68]
462 st %c26, [%i1 + globals + 200 + 72]
463 st %c27, [%i1 + globals + 200 + 76]
464 st %c28, [%i1 + globals + 200 + 80]
465 st %c29, [%i1 + globals + 200 + 84]
466 st %c30, [%i1 + globals + 200 + 88]
467 st %c31, [%i1 + globals + 200 + 92]
470 st %g1, [%i1 + globals + 200 + 96]
472 st %g1, [%i1 + globals + 200 + 100]
476 be,a L1 ! if (newsp == 0) no stack switch
479 add %i2, STACK_ALIGN - 1, %i2
480 and %i2, ~(STACK_ALIGN - 1), %i2
481 sub %i2, SA(MINFRAME), %fp
485 ! This used to compute a new stack frame base, write it into
486 ! FP, and restore to enter the new frame. But that left a window
487 ! in which FP could be written into the backing store for this
488 ! frame, to be tripped over later by returnto. So instead we do
489 ! the restore first, then modify SP to enter the new frame. We
490 ! can still refer to our argument as %02.
492 add %o2, STACK_ALIGN - 1, %o2
493 and %o2, ~(STACK_ALIGN - 1), %o2
495 sub %o2, SA(MINFRAME), %sp
498 L1: call %i0 ! call f()
503 ! struct savearea *area1;
511 ta ST_FLUSH_WINDOWS ! FLush all other active windows
512 ld [%o0+topstack],%g1 ! sp = area1->topstack
513 sub %g1, SA(MINFRAME), %fp ! Adjust sp to the right place
514 sub %fp, SA(MINFRAME), %sp
517 ld [%o0 + globals + 32 + 0],%f0 ! Restore floating-point registers
518 ld [%o0 + globals + 32 + 4],%f1
519 ld [%o0 + globals + 32 + 8],%f2
520 ld [%o0 + globals + 32 + 12],%f3
521 ld [%o0 + globals + 32 + 16],%f4
522 ld [%o0 + globals + 32 + 20],%f5
523 ld [%o0 + globals + 32 + 24],%f6
524 ld [%o0 + globals + 32 + 28],%f7
525 ld [%o0 + globals + 64 + 0],%f8
526 ld [%o0 + globals + 64 + 4],%f9
527 ld [%o0 + globals + 64 + 8],%f10
528 ld [%o0 + globals + 64 + 12],%f11
529 ld [%o0 + globals + 64 + 16],%f12
530 ld [%o0 + globals + 64 + 20],%f13
531 ld [%o0 + globals + 64 + 24],%f14
532 ld [%o0 + globals + 64 + 28],%f15
533 ld [%o0 + globals + 64 + 32],%f16
534 ld [%o0 + globals + 64 + 36],%f17
535 ld [%o0 + globals + 64 + 40],%f18
536 ld [%o0 + globals + 64 + 44],%f19
537 ld [%o0 + globals + 64 + 48],%f20
538 ld [%o0 + globals + 64 + 52],%f21
539 ld [%o0 + globals + 64 + 56],%f22
540 ld [%o0 + globals + 64 + 60],%f23
541 ld [%o0 + globals + 64 + 64],%f24
542 ld [%o0 + globals + 64 + 68],%f25
543 ld [%o0 + globals + 64 + 72],%f26
544 ld [%o0 + globals + 64 + 76],%f27
545 ld [%o0 + globals + 64 + 80],%f28
546 ld [%o0 + globals + 64 + 84],%f29
547 ld [%o0 + globals + 64 + 88],%f30
548 ld [%o0 + globals + 64 + 92],%f31
550 ld [%o0 + globals + 64 + 96],%g1
552 ld [%o0 + globals + 64 + 100],%g1
556 ld [%o0 + globals + 168 + 0],%c0 ! Restore floating-point registers
557 ld [%o0 + globals + 168 + 4],%c1
558 ld [%o0 + globals + 168 + 8],%c2
559 ld [%o0 + globals + 168 + 12],%c3
560 ld [%o0 + globals + 168 + 16],%c4
561 ld [%o0 + globals + 168 + 20],%c5
562 ld [%o0 + globals + 168 + 24],%c6
563 ld [%o0 + globals + 168 + 28],%c7
564 ld [%o0 + globals + 200 + 0],%c8
565 ld [%o0 + globals + 200 + 4],%c9
566 ld [%o0 + globals + 200 + 8],%c10
567 ld [%o0 + globals + 200 + 12],%c11
568 ld [%o0 + globals + 200 + 16],%c12
569 ld [%o0 + globals + 200 + 20],%c13
570 ld [%o0 + globals + 200 + 24],%c14
571 ld [%o0 + globals + 200 + 28],%c15
572 ld [%o0 + globals + 200 + 32],%c16
573 ld [%o0 + globals + 200 + 36],%c17
574 ld [%o0 + globals + 200 + 40],%c18
575 ld [%o0 + globals + 200 + 44],%c19
576 ld [%o0 + globals + 200 + 48],%c20
577 ld [%o0 + globals + 200 + 52],%c21
578 ld [%o0 + globals + 200 + 56],%c22
579 ld [%o0 + globals + 200 + 60],%c23
580 ld [%o0 + globals + 200 + 64],%c24
581 ld [%o0 + globals + 200 + 68],%c25
582 ld [%o0 + globals + 200 + 72],%c26
583 ld [%o0 + globals + 200 + 76],%c27
584 ld [%o0 + globals + 200 + 80],%c28
585 ld [%o0 + globals + 200 + 84],%c29
586 ld [%o0 + globals + 200 + 88],%c30
587 ld [%o0 + globals + 200 + 92],%c31
589 ld [%o0 + globals + 200 + 96],%g1
591 ld [%o0 + globals + 200 + 100],%g1
595 ld [%o0 + globals + 28], %g1 ! Restore global regs back
597 ld [%o0 + globals + 0], %g1
598 ld [%o0 + globals + 4], %g2
599 ld [%o0 + globals + 8], %g3
600 ld [%o0 + globals + 12],%g4
601 ld [%o0 + globals + 16],%g5
602 ld [%o0 + globals + 20],%g6
603 ld [%o0 + globals + 24],%g7
605 /* The following 3 lines are equivalent to: _PRE_Block = 0 */
623 | Information Technology Center
624 | Carnegie-Mellon University
640 | Process assembly language assist for Sailboats.
655 | Stuff to allow saving/restoring registers
660 | savecontext(f, area1, newsp)
661 | int (*f)(); struct savearea *area1; char *newsp;
666 ai sp,sp,-regspace | Save frame pointer & ...
667 | ... allocate space for 16 registers
669 stm r0,0(sp) | Change this if save fewer regs.
670 | Set preemption semaphore
673 putc r6,0(r7) | PRE_Block = 1
674 | r3 = base of savearea
675 put sp,topstack(r3) | area1->topstack = sp
678 be L1 | If newsp == 0, no stack switch
679 cas sp,r4,r0 | Switch to new stack
681 get r6,0(r2) | r2 = _f
687 | struct savearea *area2;
693 | Now in the context of the savecontext stack to be restored.
694 | Start with the registers...
695 | Clear preemption semaphore
698 putc r6,0(r7) | PRE_Block = 0
699 lm r0,0(sp) | Change if saving fewer regs.
700 brx r15 | Return to previous process
709 # Information Technology Center
710 # Carnegie-Mellon University
715 # Process assembly language assist for Sailboats.
732 /*# Offsets of fields*/
735 /*# Stuff to allow saving/restoring registers*/
741 # savecontext(f, area1, newsp)
742 # int (*f)(); struct savearea *area1; char *newsp;
747 ai 1,1,-regspace # Save frame pointer & ...
750 stm 0,0(1) # Change this if save fewer regs.
752 /*# Set preemption semaphore*/
756 /*# r3 = base of savearea*/
757 st 1,topstack(3) # area1->topstack = sp
758 /*# New sp is in r4.*/
760 beq L1 # If newsp == 0, no stack switch
761 cas 1,4,0 # Switch to new stack
774 # struct savearea *area2;
784 # Now in the context of the savecontext stack to be restored.
785 # Start with the registers...
786 # Clear preemption semaphore
792 lm 0,0(1) # Change if saving fewer regs.
793 brx 15 # Return to previous process
800 #endif /* AFS_AIX_ENV */
805 # Information Technology Center
806 # Carnegie-Mellon University
814 # Algorithm: "Monkey see, monkey do"
830 /* Stuff to allow saving/restoring registers */
833 # savecontext(f, area1, newsp)
834 # int (*f)(); struct savearea *area1; char *newsp;
837 /* Stack offsets of arguments */
846 .word 0x0ffc # Save regs R2-R11
847 movb $1,_PRE_Block # Critical section for preemption code
848 pushl ap # save old ap
849 pushl fp # save old fp
850 movl area1(ap),r0 # r0 = base of savearea
851 movl sp,topstack(r0) # area->topstack = sp
852 movl newsp(ap),r0 # Get new sp
853 beql L1 # if new sp is 0, dont change stacks
854 movl r0,sp # else switch to new stack
856 movl f(ap),r1 # r1 = f
859 /* It is impossible to be here, so abort() */
865 # struct savearea *area2;
868 /* Stack offset of argument */
873 .word 0x0 # Who cares about these regs?
874 movl area2(ap),r0 # r0 = address of area2
875 movl topstack(r0),sp # Restore sp
876 movl (sp)+,fp # Restore fp
878 clrb _PRE_Block # End of preemption critical section
881 pushl $1234 # The author will gloat
889 #include <regdef.h> /* Allow use of symbolic names for registers. */
890 /* 9 sregs, ra, 6 fp regs, gp, pad to 8 byte boundary */
891 #define regspace 9 * 4 + 4 + 6 * 8 + 4 + 4
893 #define registers floats + 6 * 8
894 #define returnaddr regspace - 4
896 #define GPOFF regspace - 8
897 .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
898 .ent savecontext /* Insert debugger information. */
901 .cpload t9 # set up gp for KPIC
904 .cprestore GPOFF # trigger t9/jalr
910 .frame sp, regspace, ra
911 /* Save registers. */
912 sw s0, registers + 0(sp)
913 sw s1, registers + 4(sp)
914 sw s2, registers + 8(sp)
915 sw s3, registers + 12(sp)
916 sw s4, registers + 16(sp)
917 sw s5, registers + 20(sp)
918 sw s6, registers + 24(sp)
919 sw s7, registers + 28(sp)
920 sw s8, registers + 32(sp)
921 /* Save return address */
922 sw ra, returnaddr(sp)
924 /* Need to save floating point registers? */
925 s.d $f20, floats + 0(sp)
926 s.d $f22, floats + 8(sp)
927 s.d $f24, floats + 16(sp)
928 s.d $f26, floats + 24(sp)
929 s.d $f28, floats + 32(sp)
930 s.d $f30, floats + 40(sp)
931 .fmask 0x55400000, regspace
933 beq a2, $0, samestack
944 .cpload t9 # set up gp for KPIC
948 lw s0, registers + 0(sp)
949 lw s1, registers + 4(sp)
950 lw s2, registers + 8(sp)
951 lw s3, registers + 12(sp)
952 lw s4, registers + 16(sp)
953 lw s5, registers + 20(sp)
954 lw s6, registers + 24(sp)
955 lw s7, registers + 28(sp)
956 lw s8, registers + 32(sp)
957 /* Save return address */
958 lw ra, returnaddr(sp)
959 /* Need to save floating point registers? */
960 l.d $f20, floats + 0(sp)
961 l.d $f22, floats + 8(sp)
962 l.d $f24, floats + 16(sp)
963 l.d $f26, floats + 24(sp)
964 l.d $f28, floats + 32(sp)
965 l.d $f30, floats + 40(sp)
975 /* Code for MIPS R2000/R3000 architecture
976 * Written by Zalman Stern April 30th, 1989.
978 #include <regdef.h> /* Allow use of symbolic names for registers. */
979 #define regspace 9 * 4 + 4 + 6 * 8
981 #define registers floats + 6 * 8
982 #define returnaddr regspace - 4
984 .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
985 .ent savecontext /* Insert debugger information. */
991 .frame sp, regspace, ra
992 /* Save registers. */
993 sw s0, registers + 0(sp)
994 sw s1, registers + 4(sp)
995 sw s2, registers + 8(sp)
996 sw s3, registers + 12(sp)
997 sw s4, registers + 16(sp)
998 sw s5, registers + 20(sp)
999 sw s6, registers + 24(sp)
1000 sw s7, registers + 28(sp)
1001 sw s8, registers + 32(sp)
1002 /* Save return address */
1003 sw ra, returnaddr(sp)
1004 .mask 0xc0ff0000, -4
1005 /* Need to save floating point registers? */
1006 s.d $f20, floats + 0(sp)
1007 s.d $f22, floats + 8(sp)
1008 s.d $f24, floats + 16(sp)
1009 s.d $f26, floats + 24(sp)
1010 s.d $f28, floats + 32(sp)
1011 s.d $f30, floats + 40(sp)
1012 .fmask 0x55400000, regspace
1014 beq a2, $0, samestack
1024 lw s0, registers + 0(sp)
1025 lw s1, registers + 4(sp)
1026 lw s2, registers + 8(sp)
1027 lw s3, registers + 12(sp)
1028 lw s4, registers + 16(sp)
1029 lw s5, registers + 20(sp)
1030 lw s6, registers + 24(sp)
1031 lw s7, registers + 28(sp)
1032 lw s8, registers + 32(sp)
1033 /* Save return address */
1034 lw ra, returnaddr(sp)
1035 /* Need to save floating point registers? */
1036 l.d $f20, floats + 0(sp)
1037 l.d $f22, floats + 8(sp)
1038 l.d $f24, floats + 16(sp)
1039 l.d $f26, floats + 24(sp)
1040 l.d $f28, floats + 32(sp)
1041 l.d $f30, floats + 40(sp)
1050 #include "process.s.hpux"
1051 #endif /* AFS_HPUX_ENV */
1054 /* Code for DEC Alpha architecture */
1056 #include <machine/asm.h>
1057 #include <machine/regdef.h>
1067 #include <mach/alpha/asm.h>
1070 #define FRAMESIZE ((8*8)+8+(7*8))
1072 #define registers (floats+(8*8))
1073 #define returnaddr (FRAMESIZE-8)
1079 NESTED(savecontext,FRAMESIZE,ra)
1081 NESTED(savecontext,3,FRAMESIZE,ra,0x0400f700,0x000003fc)
1086 lda sp,-FRAMESIZE(sp)
1087 /* Save callee-saved registers. */
1088 stq s0, (registers+0) (sp)
1089 stq s1, (registers+8) (sp)
1090 stq s2, (registers+16) (sp)
1091 stq s3, (registers+24) (sp)
1092 stq s4, (registers+32) (sp)
1093 stq s5, (registers+40) (sp)
1094 stq s6, (registers+48) (sp)
1095 /* Save return address */
1096 stq ra, returnaddr(sp)
1098 .mask (M_S0|M_S1|M_S2|M_S3|M_S4|M_S5|M_S6|M_RA), -FRAMESIZE
1100 /* Save floating point registers */
1101 stt fs0, (floats+0) (sp)
1102 stt fs1, (floats+8) (sp)
1103 stt fs2, (floats+16) (sp)
1104 stt fs3, (floats+24) (sp)
1105 stt fs4, (floats+32) (sp)
1106 stt fs5, (floats+40) (sp)
1107 stt fs6, (floats+48) (sp)
1108 stt fs7, (floats+56) (sp)
1111 stq sp, topstack(a1)
1112 or a0,zero,pv /* call point in pv */
1114 or a2,zero,sp /* switch stack */
1116 jsr ra,(pv),0 /* off we go */
1127 ldq sp, topstack(a0)
1128 /* Restore callee-saved regs */
1129 ldq s0, (registers+0) (sp)
1130 ldq s1, (registers+8) (sp)
1131 ldq s2, (registers+16) (sp)
1132 ldq s3, (registers+24) (sp)
1133 ldq s4, (registers+32) (sp)
1134 ldq s5, (registers+40) (sp)
1135 ldq s6, (registers+48) (sp)
1136 /* Return address */
1137 ldq ra, returnaddr(sp)
1138 /* Floating point registers */
1139 ldt fs0, (floats+0) (sp)
1140 ldt fs1, (floats+8) (sp)
1141 ldt fs2, (floats+16) (sp)
1142 ldt fs3, (floats+24) (sp)
1143 ldt fs4, (floats+32) (sp)
1144 ldt fs5, (floats+40) (sp)
1145 ldt fs6, (floats+48) (sp)
1146 ldt fs7, (floats+56) (sp)
1147 lda sp, FRAMESIZE(sp)
1153 #if defined(AFS_NCR_ENV) || defined(AFS_X86_ENV)
1154 /* Sun 386i... I hope this does the right thing!!!
1156 * Written by Derek Atkins <warlord@MIT.EDU>
1157 * (debugging help by Chris Provenzano <proven@mit.edu>)
1160 * "ojala que es correcto!"
1177 * savecontext(f, area1, newsp)
1178 * int (*f)(); struct savearea *area1; char *newsp;
1181 /* offsets, to make my life easier! */
1191 pushl %ebp /* New Frame! */
1193 pusha /* Push all registers */
1194 movl $1,PRE_Block /* Pre-emption code */
1195 movl area1(%ebp),%eax /* eax = base of savearea */
1196 movl %esp,(%eax) /* area->topstack = esp */
1197 movl newsp(%ebp),%eax /* get new sp into eax */
1199 je L1 /* if new sp is 0 then dont change esp */
1200 movl %eax,%esp /* go ahead. make my day! */
1202 jmp *f(%ebp) /* ebx = &f */
1204 /* Shouldnt be here....*/
1210 * struct savearea *area2;
1220 movl %esp, %ebp /* New frame, to get correct pointer */
1221 movl area2(%ebp),%eax /* eax = area2 */
1222 movl (%eax),%esp /* restore esp */
1224 movl $0,PRE_Block /* clear it up... */
1228 /* I see, said the blind man, as he picked up his hammer and saw! */
1233 #endif /* AFS_NCR_ENV */