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]
172 # Information Technology Center
173 # Carnegie-Mellon University
181 # Process assembly language assist for Suns.
200 /* Stuff to allow saving/restoring registers */
202 regs = 0x3ffe | d1-d7 & a0-a5
205 # savecontext(f, area1, newsp)
206 # int (*f)(); struct savearea *area1; char *newsp;
209 /* Stack offsets of arguments */
216 movb #1,_PRE_Block | Dont allow any interrupt finagling
217 link a6,#-(nregs*4) | Save frame pointer & ...
218 | ... allocate space for nregs registers
222 movl a6@(area1),a0 | a0 = base of savearea
223 movl sp,a0@(topstack) | area->topstack = sp
224 movl a6@(newsp),d0 | Get new sp
225 jeq forw1 | If newsp == 0, no stack switch
226 movl d0,sp | Switch to new stack
228 movl a6@(f),a0 | a0 = f
231 /* It is impossible to be here, so abort() */
237 # struct savearea *area2;
240 /* Stack offset of argument */
246 movl a6@(area2),a0 | Base of savearea
247 movl a0@(topstack),sp | Restore sp
248 /* Restore registers */
252 movl sp,a6 | Argghh...be careful here
255 rts | Return to previous process
260 #include <sys/asm_linkage.h>
261 #include <sys/trap.h>
263 #include <sun4/asm_linkage.h>
264 #include <sun4/trap.h>
275 # savecontext(f, area1, newsp)
276 # int (*f)(); struct savearea *area1; char *newsp;
286 save %sp, -SA(MINFRAME), %sp ! Get new window
287 ta ST_FLUSH_WINDOWS ! FLush all other active windows
289 /* The following 3 lines do the equivalent of: _PRE_Block = 1 */
298 st %fp,[%i1+topstack] ! area1->topstack = sp
300 st %g1, [%i1 + globals + 0] /* Save all globals just in case */
301 st %g2, [%i1 + globals + 4]
302 st %g3, [%i1 + globals + 8]
303 st %g4, [%i1 + globals + 12]
304 st %g5, [%i1 + globals + 16]
305 st %g6, [%i1 + globals + 20]
306 st %g7, [%i1 + globals + 24]
308 st %g1, [%i1 + globals + 28]
311 st %f0, [%i1 + globals + 32 + 0] ! Save all floating point registers
312 st %f1, [%i1 + globals + 32 + 4]
313 st %f2, [%i1 + globals + 32 + 8]
314 st %f3, [%i1 + globals + 32 + 12]
315 st %f4, [%i1 + globals + 32 + 16]
316 st %f5, [%i1 + globals + 32 + 20]
317 st %f6, [%i1 + globals + 32 + 24]
318 st %f7, [%i1 + globals + 32 + 28]
319 st %f8, [%i1 + globals + 64 + 0]
320 st %f9, [%i1 + globals + 64 + 4]
321 st %f10, [%i1 + globals + 64 + 8]
322 st %f11, [%i1 + globals + 64 + 12]
323 st %f12, [%i1 + globals + 64 + 16]
324 st %f13, [%i1 + globals + 64 + 20]
325 st %f14, [%i1 + globals + 64 + 24]
326 st %f15, [%i1 + globals + 64 + 28]
327 st %f16, [%i1 + globals + 64 + 32]
328 st %f17, [%i1 + globals + 64 + 36]
329 st %f18, [%i1 + globals + 64 + 40]
330 st %f19, [%i1 + globals + 64 + 44]
331 st %f20, [%i1 + globals + 64 + 48]
332 st %f21, [%i1 + globals + 64 + 52]
333 st %f22, [%i1 + globals + 64 + 56]
334 st %f23, [%i1 + globals + 64 + 60]
335 st %f24, [%i1 + globals + 64 + 64]
336 st %f25, [%i1 + globals + 64 + 68]
337 st %f26, [%i1 + globals + 64 + 72]
338 st %f27, [%i1 + globals + 64 + 76]
339 st %f28, [%i1 + globals + 64 + 80]
340 st %f29, [%i1 + globals + 64 + 84]
341 st %f30, [%i1 + globals + 64 + 88]
342 st %f31, [%i1 + globals + 64 + 92]
345 st %g1, [%i1 + globals + 64 + 96]
347 st %g1, [%i1 + globals + 64 + 100]
350 st %c0, [%i1 + globals + 168 + 0] ! Save all coprocessor registers
351 st %c1, [%i1 + globals + 168 + 4]
352 st %c2, [%i1 + globals + 168 + 8]
353 st %c3, [%i1 + globals + 168 + 12]
354 st %c4, [%i1 + globals + 168 + 16]
355 st %c5, [%i1 + globals + 168 + 20]
356 st %c6, [%i1 + globals + 168 + 24]
357 st %c7, [%i1 + globals + 168 + 28]
358 st %c8, [%i1 + globals + 200 + 0]
359 st %c9, [%i1 + globals + 200 + 4]
360 st %c10, [%i1 + globals + 200 + 8]
361 st %c11, [%i1 + globals + 200 + 12]
362 st %c12, [%i1 + globals + 200 + 16]
363 st %c13, [%i1 + globals + 200 + 20]
364 st %c14, [%i1 + globals + 200 + 24]
365 st %c15, [%i1 + globals + 200 + 28]
366 st %c16, [%i1 + globals + 200 + 32]
367 st %c17, [%i1 + globals + 200 + 36]
368 st %c18, [%i1 + globals + 200 + 40]
369 st %c19, [%i1 + globals + 200 + 44]
370 st %c20, [%i1 + globals + 200 + 48]
371 st %c21, [%i1 + globals + 200 + 52]
372 st %c22, [%i1 + globals + 200 + 56]
373 st %c23, [%i1 + globals + 200 + 60]
374 st %c24, [%i1 + globals + 200 + 64]
375 st %c25, [%i1 + globals + 200 + 68]
376 st %c26, [%i1 + globals + 200 + 72]
377 st %c27, [%i1 + globals + 200 + 76]
378 st %c28, [%i1 + globals + 200 + 80]
379 st %c29, [%i1 + globals + 200 + 84]
380 st %c30, [%i1 + globals + 200 + 88]
381 st %c31, [%i1 + globals + 200 + 92]
384 st %g1, [%i1 + globals + 200 + 96]
386 st %g1, [%i1 + globals + 200 + 100]
390 be,a L1 ! if (newsp == 0) no stack switch
393 add %i2, STACK_ALIGN - 1, %i2
394 and %i2, ~(STACK_ALIGN - 1), %i2
395 sub %i2, SA(MINFRAME), %fp
399 ! This used to compute a new stack frame base, write it into
400 ! FP, and restore to enter the new frame. But that left a window
401 ! in which FP could be written into the backing store for this
402 ! frame, to be tripped over later by returnto. So instead we do
403 ! the restore first, then modify SP to enter the new frame. We
404 ! can still refer to our argument as %02.
406 add %o2, STACK_ALIGN - 1, %o2
407 and %o2, ~(STACK_ALIGN - 1), %o2
409 sub %o2, SA(MINFRAME), %sp
412 L1: call %i0 ! call f()
417 ! struct savearea *area1;
425 ta ST_FLUSH_WINDOWS ! FLush all other active windows
426 ld [%o0+topstack],%g1 ! sp = area1->topstack
427 sub %g1, SA(MINFRAME), %fp ! Adjust sp to the right place
428 sub %fp, SA(MINFRAME), %sp
431 ld [%o0 + globals + 32 + 0],%f0 ! Restore floating-point registers
432 ld [%o0 + globals + 32 + 4],%f1
433 ld [%o0 + globals + 32 + 8],%f2
434 ld [%o0 + globals + 32 + 12],%f3
435 ld [%o0 + globals + 32 + 16],%f4
436 ld [%o0 + globals + 32 + 20],%f5
437 ld [%o0 + globals + 32 + 24],%f6
438 ld [%o0 + globals + 32 + 28],%f7
439 ld [%o0 + globals + 64 + 0],%f8
440 ld [%o0 + globals + 64 + 4],%f9
441 ld [%o0 + globals + 64 + 8],%f10
442 ld [%o0 + globals + 64 + 12],%f11
443 ld [%o0 + globals + 64 + 16],%f12
444 ld [%o0 + globals + 64 + 20],%f13
445 ld [%o0 + globals + 64 + 24],%f14
446 ld [%o0 + globals + 64 + 28],%f15
447 ld [%o0 + globals + 64 + 32],%f16
448 ld [%o0 + globals + 64 + 36],%f17
449 ld [%o0 + globals + 64 + 40],%f18
450 ld [%o0 + globals + 64 + 44],%f19
451 ld [%o0 + globals + 64 + 48],%f20
452 ld [%o0 + globals + 64 + 52],%f21
453 ld [%o0 + globals + 64 + 56],%f22
454 ld [%o0 + globals + 64 + 60],%f23
455 ld [%o0 + globals + 64 + 64],%f24
456 ld [%o0 + globals + 64 + 68],%f25
457 ld [%o0 + globals + 64 + 72],%f26
458 ld [%o0 + globals + 64 + 76],%f27
459 ld [%o0 + globals + 64 + 80],%f28
460 ld [%o0 + globals + 64 + 84],%f29
461 ld [%o0 + globals + 64 + 88],%f30
462 ld [%o0 + globals + 64 + 92],%f31
464 ld [%o0 + globals + 64 + 96],%g1
466 ld [%o0 + globals + 64 + 100],%g1
470 ld [%o0 + globals + 168 + 0],%c0 ! Restore floating-point registers
471 ld [%o0 + globals + 168 + 4],%c1
472 ld [%o0 + globals + 168 + 8],%c2
473 ld [%o0 + globals + 168 + 12],%c3
474 ld [%o0 + globals + 168 + 16],%c4
475 ld [%o0 + globals + 168 + 20],%c5
476 ld [%o0 + globals + 168 + 24],%c6
477 ld [%o0 + globals + 168 + 28],%c7
478 ld [%o0 + globals + 200 + 0],%c8
479 ld [%o0 + globals + 200 + 4],%c9
480 ld [%o0 + globals + 200 + 8],%c10
481 ld [%o0 + globals + 200 + 12],%c11
482 ld [%o0 + globals + 200 + 16],%c12
483 ld [%o0 + globals + 200 + 20],%c13
484 ld [%o0 + globals + 200 + 24],%c14
485 ld [%o0 + globals + 200 + 28],%c15
486 ld [%o0 + globals + 200 + 32],%c16
487 ld [%o0 + globals + 200 + 36],%c17
488 ld [%o0 + globals + 200 + 40],%c18
489 ld [%o0 + globals + 200 + 44],%c19
490 ld [%o0 + globals + 200 + 48],%c20
491 ld [%o0 + globals + 200 + 52],%c21
492 ld [%o0 + globals + 200 + 56],%c22
493 ld [%o0 + globals + 200 + 60],%c23
494 ld [%o0 + globals + 200 + 64],%c24
495 ld [%o0 + globals + 200 + 68],%c25
496 ld [%o0 + globals + 200 + 72],%c26
497 ld [%o0 + globals + 200 + 76],%c27
498 ld [%o0 + globals + 200 + 80],%c28
499 ld [%o0 + globals + 200 + 84],%c29
500 ld [%o0 + globals + 200 + 88],%c30
501 ld [%o0 + globals + 200 + 92],%c31
503 ld [%o0 + globals + 200 + 96],%g1
505 ld [%o0 + globals + 200 + 100],%g1
509 ld [%o0 + globals + 28], %g1 ! Restore global regs back
511 ld [%o0 + globals + 0], %g1
512 ld [%o0 + globals + 4], %g2
513 ld [%o0 + globals + 8], %g3
514 ld [%o0 + globals + 12],%g4
515 ld [%o0 + globals + 16],%g5
516 ld [%o0 + globals + 20],%g6
517 ld [%o0 + globals + 24],%g7
519 /* The following 3 lines are equivalent to: _PRE_Block = 0 */
537 | Information Technology Center
538 | Carnegie-Mellon University
554 | Process assembly language assist for Sailboats.
569 | Stuff to allow saving/restoring registers
574 | savecontext(f, area1, newsp)
575 | int (*f)(); struct savearea *area1; char *newsp;
580 ai sp,sp,-regspace | Save frame pointer & ...
581 | ... allocate space for 16 registers
583 stm r0,0(sp) | Change this if save fewer regs.
584 | Set preemption semaphore
587 putc r6,0(r7) | PRE_Block = 1
588 | r3 = base of savearea
589 put sp,topstack(r3) | area1->topstack = sp
592 be L1 | If newsp == 0, no stack switch
593 cas sp,r4,r0 | Switch to new stack
595 get r6,0(r2) | r2 = _f
601 | struct savearea *area2;
607 | Now in the context of the savecontext stack to be restored.
608 | Start with the registers...
609 | Clear preemption semaphore
612 putc r6,0(r7) | PRE_Block = 0
613 lm r0,0(sp) | Change if saving fewer regs.
614 brx r15 | Return to previous process
623 # Information Technology Center
624 # Carnegie-Mellon University
629 # Process assembly language assist for Sailboats.
646 /*# Offsets of fields*/
649 /*# Stuff to allow saving/restoring registers*/
655 # savecontext(f, area1, newsp)
656 # int (*f)(); struct savearea *area1; char *newsp;
661 ai 1,1,-regspace # Save frame pointer & ...
664 stm 0,0(1) # Change this if save fewer regs.
666 /*# Set preemption semaphore*/
670 /*# r3 = base of savearea*/
671 st 1,topstack(3) # area1->topstack = sp
672 /*# New sp is in r4.*/
674 beq L1 # If newsp == 0, no stack switch
675 cas 1,4,0 # Switch to new stack
688 # struct savearea *area2;
698 # Now in the context of the savecontext stack to be restored.
699 # Start with the registers...
700 # Clear preemption semaphore
706 lm 0,0(1) # Change if saving fewer regs.
707 brx 15 # Return to previous process
714 #endif /* AFS_AIX_ENV */
719 # Information Technology Center
720 # Carnegie-Mellon University
728 # Algorithm: "Monkey see, monkey do"
744 /* Stuff to allow saving/restoring registers */
747 # savecontext(f, area1, newsp)
748 # int (*f)(); struct savearea *area1; char *newsp;
751 /* Stack offsets of arguments */
760 .word 0x0ffc # Save regs R2-R11
761 movb $1,_PRE_Block # Critical section for preemption code
762 pushl ap # save old ap
763 pushl fp # save old fp
764 movl area1(ap),r0 # r0 = base of savearea
765 movl sp,topstack(r0) # area->topstack = sp
766 movl newsp(ap),r0 # Get new sp
767 beql L1 # if new sp is 0, dont change stacks
768 movl r0,sp # else switch to new stack
770 movl f(ap),r1 # r1 = f
773 /* It is impossible to be here, so abort() */
779 # struct savearea *area2;
782 /* Stack offset of argument */
787 .word 0x0 # Who cares about these regs?
788 movl area2(ap),r0 # r0 = address of area2
789 movl topstack(r0),sp # Restore sp
790 movl (sp)+,fp # Restore fp
792 clrb _PRE_Block # End of preemption critical section
795 pushl $1234 # The author will gloat
803 #include <regdef.h> /* Allow use of symbolic names for registers. */
804 /* 9 sregs, ra, 6 fp regs, gp, pad to 8 byte boundary */
805 #define regspace 9 * 4 + 4 + 6 * 8 + 4 + 4
807 #define registers floats + 6 * 8
808 #define returnaddr regspace - 4
810 #define GPOFF regspace - 8
811 .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
812 .ent savecontext /* Insert debugger information. */
815 .cpload t9 # set up gp for KPIC
818 .cprestore GPOFF # trigger t9/jalr
824 .frame sp, regspace, ra
825 /* Save registers. */
826 sw s0, registers + 0(sp)
827 sw s1, registers + 4(sp)
828 sw s2, registers + 8(sp)
829 sw s3, registers + 12(sp)
830 sw s4, registers + 16(sp)
831 sw s5, registers + 20(sp)
832 sw s6, registers + 24(sp)
833 sw s7, registers + 28(sp)
834 sw s8, registers + 32(sp)
835 /* Save return address */
836 sw ra, returnaddr(sp)
838 /* Need to save floating point registers? */
839 s.d $f20, floats + 0(sp)
840 s.d $f22, floats + 8(sp)
841 s.d $f24, floats + 16(sp)
842 s.d $f26, floats + 24(sp)
843 s.d $f28, floats + 32(sp)
844 s.d $f30, floats + 40(sp)
845 .fmask 0x55400000, regspace
847 beq a2, $0, samestack
858 .cpload t9 # set up gp for KPIC
862 lw s0, registers + 0(sp)
863 lw s1, registers + 4(sp)
864 lw s2, registers + 8(sp)
865 lw s3, registers + 12(sp)
866 lw s4, registers + 16(sp)
867 lw s5, registers + 20(sp)
868 lw s6, registers + 24(sp)
869 lw s7, registers + 28(sp)
870 lw s8, registers + 32(sp)
871 /* Save return address */
872 lw ra, returnaddr(sp)
873 /* Need to save floating point registers? */
874 l.d $f20, floats + 0(sp)
875 l.d $f22, floats + 8(sp)
876 l.d $f24, floats + 16(sp)
877 l.d $f26, floats + 24(sp)
878 l.d $f28, floats + 32(sp)
879 l.d $f30, floats + 40(sp)
889 /* Code for MIPS R2000/R3000 architecture
890 * Written by Zalman Stern April 30th, 1989.
892 #include <regdef.h> /* Allow use of symbolic names for registers. */
893 #define regspace 9 * 4 + 4 + 6 * 8
895 #define registers floats + 6 * 8
896 #define returnaddr regspace - 4
898 .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
899 .ent savecontext /* Insert debugger information. */
905 .frame sp, regspace, ra
906 /* Save registers. */
907 sw s0, registers + 0(sp)
908 sw s1, registers + 4(sp)
909 sw s2, registers + 8(sp)
910 sw s3, registers + 12(sp)
911 sw s4, registers + 16(sp)
912 sw s5, registers + 20(sp)
913 sw s6, registers + 24(sp)
914 sw s7, registers + 28(sp)
915 sw s8, registers + 32(sp)
916 /* Save return address */
917 sw ra, returnaddr(sp)
919 /* Need to save floating point registers? */
920 s.d $f20, floats + 0(sp)
921 s.d $f22, floats + 8(sp)
922 s.d $f24, floats + 16(sp)
923 s.d $f26, floats + 24(sp)
924 s.d $f28, floats + 32(sp)
925 s.d $f30, floats + 40(sp)
926 .fmask 0x55400000, regspace
928 beq a2, $0, samestack
938 lw s0, registers + 0(sp)
939 lw s1, registers + 4(sp)
940 lw s2, registers + 8(sp)
941 lw s3, registers + 12(sp)
942 lw s4, registers + 16(sp)
943 lw s5, registers + 20(sp)
944 lw s6, registers + 24(sp)
945 lw s7, registers + 28(sp)
946 lw s8, registers + 32(sp)
947 /* Save return address */
948 lw ra, returnaddr(sp)
949 /* Need to save floating point registers? */
950 l.d $f20, floats + 0(sp)
951 l.d $f22, floats + 8(sp)
952 l.d $f24, floats + 16(sp)
953 l.d $f26, floats + 24(sp)
954 l.d $f28, floats + 32(sp)
955 l.d $f30, floats + 40(sp)
964 #include "process.s.hpux"
965 #endif /* AFS_HPUX_ENV */
968 /* Code for DEC Alpha architecture */
970 #include <machine/asm.h>
971 #include <machine/regdef.h>
981 #include <mach/alpha/asm.h>
984 #define FRAMESIZE ((8*8)+8+(7*8))
986 #define registers (floats+(8*8))
987 #define returnaddr (FRAMESIZE-8)
993 NESTED(savecontext,FRAMESIZE,ra)
995 NESTED(savecontext,3,FRAMESIZE,ra,0x0400f700,0x000003fc)
1000 lda sp,-FRAMESIZE(sp)
1001 /* Save callee-saved registers. */
1002 stq s0, (registers+0) (sp)
1003 stq s1, (registers+8) (sp)
1004 stq s2, (registers+16) (sp)
1005 stq s3, (registers+24) (sp)
1006 stq s4, (registers+32) (sp)
1007 stq s5, (registers+40) (sp)
1008 stq s6, (registers+48) (sp)
1009 /* Save return address */
1010 stq ra, returnaddr(sp)
1012 .mask (M_S0|M_S1|M_S2|M_S3|M_S4|M_S5|M_S6|M_RA), -FRAMESIZE
1014 /* Save floating point registers */
1015 stt fs0, (floats+0) (sp)
1016 stt fs1, (floats+8) (sp)
1017 stt fs2, (floats+16) (sp)
1018 stt fs3, (floats+24) (sp)
1019 stt fs4, (floats+32) (sp)
1020 stt fs5, (floats+40) (sp)
1021 stt fs6, (floats+48) (sp)
1022 stt fs7, (floats+56) (sp)
1025 stq sp, topstack(a1)
1026 or a0,zero,pv /* call point in pv */
1028 or a2,zero,sp /* switch stack */
1030 jsr ra,(pv),0 /* off we go */
1041 ldq sp, topstack(a0)
1042 /* Restore callee-saved regs */
1043 ldq s0, (registers+0) (sp)
1044 ldq s1, (registers+8) (sp)
1045 ldq s2, (registers+16) (sp)
1046 ldq s3, (registers+24) (sp)
1047 ldq s4, (registers+32) (sp)
1048 ldq s5, (registers+40) (sp)
1049 ldq s6, (registers+48) (sp)
1050 /* Return address */
1051 ldq ra, returnaddr(sp)
1052 /* Floating point registers */
1053 ldt fs0, (floats+0) (sp)
1054 ldt fs1, (floats+8) (sp)
1055 ldt fs2, (floats+16) (sp)
1056 ldt fs3, (floats+24) (sp)
1057 ldt fs4, (floats+32) (sp)
1058 ldt fs5, (floats+40) (sp)
1059 ldt fs6, (floats+48) (sp)
1060 ldt fs7, (floats+56) (sp)
1061 lda sp, FRAMESIZE(sp)
1067 #if defined(AFS_NCR_ENV) || defined(AFS_X86_ENV)
1068 /* Sun 386i... I hope this does the right thing!!!
1070 * Written by Derek Atkins <warlord@MIT.EDU>
1071 * (debugging help by Chris Provenzano <proven@mit.edu>)
1074 * "ojala que es correcto!"
1091 * savecontext(f, area1, newsp)
1092 * int (*f)(); struct savearea *area1; char *newsp;
1095 /* offsets, to make my life easier! */
1105 pushl %ebp /* New Frame! */
1107 pusha /* Push all registers */
1108 movl $1,PRE_Block /* Pre-emption code */
1109 movl area1(%ebp),%eax /* eax = base of savearea */
1110 movl %esp,(%eax) /* area->topstack = esp */
1111 movl newsp(%ebp),%eax /* get new sp into eax */
1113 je L1 /* if new sp is 0 then dont change esp */
1114 movl %eax,%esp /* go ahead. make my day! */
1116 jmp *f(%ebp) /* ebx = &f */
1118 /* Shouldnt be here....*/
1124 * struct savearea *area2;
1134 movl %esp, %ebp /* New frame, to get correct pointer */
1135 movl area2(%ebp),%eax /* eax = area2 */
1136 movl (%eax),%esp /* restore esp */
1138 movl $0,PRE_Block /* clear it up... */
1142 /* I see, said the blind man, as he picked up his hammer and saw! */
1147 #endif /* AFS_NCR_ENV */