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 #ifndef AFS_ARM_DARWIN_ENV
15 /* register definitions */
24 savecontext(f, area1, newsp)
25 int (*f)()#if defined(RIOS);
26 struct savearea *area1;
30 /* Arguments appear as: f in r0, area1 in r1, newsp in r2 */
34 #ifndef AFS_ARM_DARWIN_ENV
36 .type savecontext, #function
44 stmfd sp!, {fp, ip, lr, pc}
46 @ stack r0 - r10, current fp
47 stmfd sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, fp}
49 @ check if newsp is zero
53 #ifdef AFS_ARM_DARWIN_ENV
61 struct savearea *area2;
66 #ifndef AFS_ARM_DARWIN_ENV
68 .type returnto, #function
76 ldmfd r0, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, fp}
77 @ return from function call
78 ldmea fp, {fp, sp, pc}
80 #endif /* __arm32__ or __arm__ */
83 /* I don't know if we have to save the TOC (R2) or not...
84 * Note that stack-frame is supposed to be aligned on
85 * a double-word boundary.
86 * For details about RIOS calling conventions
87 * see the Assembler manual and /usr/include/sys/asdef.s
92 * savecontext(f, area1, newsp)
93 * int (*f)(); struct savearea *area1; char *newsp;
115 .set szdsa, 8*nfprs+4*ngprs+linkarea+argarea
117 .csect .savecontext[PR]
118 .globl .savecontext[PR]
120 mflr r0 # save link register
123 * save floating point registers. Interleave some other stuff for
124 * timing reasons. Set up conditions and registers for branches
125 * early, so that processor can prefetch instructions.
135 l 11, 0(a_f) # r11 <- *(a_f)
140 cmpi cr0, a_newsp, 0 # cr0 <- (a_newsp :: 0)
146 mtlr 11 # set up lr early so prefetch works
152 st r0, 8(r1) # save return addr
158 st 12, 4(r1) # save CR
165 * save general-purpose registers
167 stm 12, -8*nfprs-4*ngprs(r1)# save the general-purpose regs
168 stu r1, -szdsa(r1) # dec SP and save back chain
170 l r7, PRE_Block.S(toc) # r7 <- &PRE_Block
171 cal r6, 1(r0) # r6 <- #1
172 stb r6, 0(r7) # r6 -> PRE_Block
174 st r1, topstack(a_area1) # save old SP
176 beq L1 # if (a_newsp == 0) goto L1
178 mr r1, r5 # r1 <- a_newsp -- load new SP
180 L1: brl # pc <- lr -- (*a_f)()
183 * returnto(area2) This is a little jumbled, I tried to interleave
184 * memory accesses with simple instructions for speed, and I tried to
185 * set up the link register and condition register reasonably early
186 * so that processor instruction prefetching might help us out a little.
193 l r1, topstack(a_area2) # r1 <- a_area2->topstack
194 cal r1, szdsa(r1) # pop off frame
195 l r7, PRE_Block.S(toc) # r7 <- &PRE_Block
197 l 8, 8(1) # restore lr
198 mtlr 8 # do it early so prefetch works
200 lm 12, -8*nfprs-4*ngprs(r1)
201 cal r6, 0(r0) # r6 <- #0
202 mtcrf 0x38, 12 # put back cr
203 stb r6, 0(r7) # r6 -> PRE_Block
227 brl # pc <- lr -- return
232 .tc PRE_Block[tc], PRE_Block[ua]
233 .extern PRE_Block[ua]
240 # Information Technology Center
241 # Carnegie-Mellon University
249 # Process assembly language assist for Suns.
268 /* Stuff to allow saving/restoring registers */
270 regs = 0x3ffe | d1-d7 & a0-a5
273 # savecontext(f, area1, newsp)
274 # int (*f)(); struct savearea *area1; char *newsp;
277 /* Stack offsets of arguments */
284 movb #1,_PRE_Block | Dont allow any interrupt finagling
285 link a6,#-(nregs*4) | Save frame pointer & ...
286 | ... allocate space for nregs registers
290 movl a6@(area1),a0 | a0 = base of savearea
291 movl sp,a0@(topstack) | area->topstack = sp
292 movl a6@(newsp),d0 | Get new sp
293 jeq forw1 | If newsp == 0, no stack switch
294 movl d0,sp | Switch to new stack
296 movl a6@(f),a0 | a0 = f
299 /* It is impossible to be here, so abort() */
305 # struct savearea *area2;
308 /* Stack offset of argument */
314 movl a6@(area2),a0 | Base of savearea
315 movl a0@(topstack),sp | Restore sp
316 /* Restore registers */
320 movl sp,a6 | Argghh...be careful here
323 rts | Return to previous process
328 #include <sys/asm_linkage.h>
329 #include <sys/trap.h>
332 #include <machine/trap.h>
333 #define ST_FLUSH_WINDOWS ST_FLUSHWIN
335 #define SA(x) (((x)+7)&~7)
336 #define STACK_ALIGN 8
338 #include <sun4/asm_linkage.h>
339 #include <sun4/trap.h>
351 # savecontext(f, area1, newsp)
352 # int (*f)(); struct savearea *area1; char *newsp;
362 save %sp, -SA(MINFRAME), %sp ! Get new window
363 ta ST_FLUSH_WINDOWS ! FLush all other active windows
365 /* The following 3 lines do the equivalent of: _PRE_Block = 1 */
374 st %fp,[%i1+topstack] ! area1->topstack = sp
376 st %g1, [%i1 + globals + 0] /* Save all globals just in case */
377 st %g2, [%i1 + globals + 4]
378 st %g3, [%i1 + globals + 8]
379 st %g4, [%i1 + globals + 12]
380 st %g5, [%i1 + globals + 16]
381 st %g6, [%i1 + globals + 20]
382 st %g7, [%i1 + globals + 24]
384 st %g1, [%i1 + globals + 28]
387 st %f0, [%i1 + globals + 32 + 0] ! Save all floating point registers
388 st %f1, [%i1 + globals + 32 + 4]
389 st %f2, [%i1 + globals + 32 + 8]
390 st %f3, [%i1 + globals + 32 + 12]
391 st %f4, [%i1 + globals + 32 + 16]
392 st %f5, [%i1 + globals + 32 + 20]
393 st %f6, [%i1 + globals + 32 + 24]
394 st %f7, [%i1 + globals + 32 + 28]
395 st %f8, [%i1 + globals + 64 + 0]
396 st %f9, [%i1 + globals + 64 + 4]
397 st %f10, [%i1 + globals + 64 + 8]
398 st %f11, [%i1 + globals + 64 + 12]
399 st %f12, [%i1 + globals + 64 + 16]
400 st %f13, [%i1 + globals + 64 + 20]
401 st %f14, [%i1 + globals + 64 + 24]
402 st %f15, [%i1 + globals + 64 + 28]
403 st %f16, [%i1 + globals + 64 + 32]
404 st %f17, [%i1 + globals + 64 + 36]
405 st %f18, [%i1 + globals + 64 + 40]
406 st %f19, [%i1 + globals + 64 + 44]
407 st %f20, [%i1 + globals + 64 + 48]
408 st %f21, [%i1 + globals + 64 + 52]
409 st %f22, [%i1 + globals + 64 + 56]
410 st %f23, [%i1 + globals + 64 + 60]
411 st %f24, [%i1 + globals + 64 + 64]
412 st %f25, [%i1 + globals + 64 + 68]
413 st %f26, [%i1 + globals + 64 + 72]
414 st %f27, [%i1 + globals + 64 + 76]
415 st %f28, [%i1 + globals + 64 + 80]
416 st %f29, [%i1 + globals + 64 + 84]
417 st %f30, [%i1 + globals + 64 + 88]
418 st %f31, [%i1 + globals + 64 + 92]
421 st %g1, [%i1 + globals + 64 + 96]
423 st %g1, [%i1 + globals + 64 + 100]
426 st %c0, [%i1 + globals + 168 + 0] ! Save all coprocessor registers
427 st %c1, [%i1 + globals + 168 + 4]
428 st %c2, [%i1 + globals + 168 + 8]
429 st %c3, [%i1 + globals + 168 + 12]
430 st %c4, [%i1 + globals + 168 + 16]
431 st %c5, [%i1 + globals + 168 + 20]
432 st %c6, [%i1 + globals + 168 + 24]
433 st %c7, [%i1 + globals + 168 + 28]
434 st %c8, [%i1 + globals + 200 + 0]
435 st %c9, [%i1 + globals + 200 + 4]
436 st %c10, [%i1 + globals + 200 + 8]
437 st %c11, [%i1 + globals + 200 + 12]
438 st %c12, [%i1 + globals + 200 + 16]
439 st %c13, [%i1 + globals + 200 + 20]
440 st %c14, [%i1 + globals + 200 + 24]
441 st %c15, [%i1 + globals + 200 + 28]
442 st %c16, [%i1 + globals + 200 + 32]
443 st %c17, [%i1 + globals + 200 + 36]
444 st %c18, [%i1 + globals + 200 + 40]
445 st %c19, [%i1 + globals + 200 + 44]
446 st %c20, [%i1 + globals + 200 + 48]
447 st %c21, [%i1 + globals + 200 + 52]
448 st %c22, [%i1 + globals + 200 + 56]
449 st %c23, [%i1 + globals + 200 + 60]
450 st %c24, [%i1 + globals + 200 + 64]
451 st %c25, [%i1 + globals + 200 + 68]
452 st %c26, [%i1 + globals + 200 + 72]
453 st %c27, [%i1 + globals + 200 + 76]
454 st %c28, [%i1 + globals + 200 + 80]
455 st %c29, [%i1 + globals + 200 + 84]
456 st %c30, [%i1 + globals + 200 + 88]
457 st %c31, [%i1 + globals + 200 + 92]
460 st %g1, [%i1 + globals + 200 + 96]
462 st %g1, [%i1 + globals + 200 + 100]
466 be,a L1 ! if (newsp == 0) no stack switch
469 add %i2, STACK_ALIGN - 1, %i2
470 and %i2, ~(STACK_ALIGN - 1), %i2
471 sub %i2, SA(MINFRAME), %fp
475 ! This used to compute a new stack frame base, write it into
476 ! FP, and restore to enter the new frame. But that left a window
477 ! in which FP could be written into the backing store for this
478 ! frame, to be tripped over later by returnto. So instead we do
479 ! the restore first, then modify SP to enter the new frame. We
480 ! can still refer to our argument as %02.
482 add %o2, STACK_ALIGN - 1, %o2
483 and %o2, ~(STACK_ALIGN - 1), %o2
485 sub %o2, SA(MINFRAME), %sp
488 L1: call %i0 ! call f()
493 ! struct savearea *area1;
501 ta ST_FLUSH_WINDOWS ! FLush all other active windows
502 ld [%o0+topstack],%g1 ! sp = area1->topstack
503 sub %g1, SA(MINFRAME), %fp ! Adjust sp to the right place
504 sub %fp, SA(MINFRAME), %sp
507 ld [%o0 + globals + 32 + 0],%f0 ! Restore floating-point registers
508 ld [%o0 + globals + 32 + 4],%f1
509 ld [%o0 + globals + 32 + 8],%f2
510 ld [%o0 + globals + 32 + 12],%f3
511 ld [%o0 + globals + 32 + 16],%f4
512 ld [%o0 + globals + 32 + 20],%f5
513 ld [%o0 + globals + 32 + 24],%f6
514 ld [%o0 + globals + 32 + 28],%f7
515 ld [%o0 + globals + 64 + 0],%f8
516 ld [%o0 + globals + 64 + 4],%f9
517 ld [%o0 + globals + 64 + 8],%f10
518 ld [%o0 + globals + 64 + 12],%f11
519 ld [%o0 + globals + 64 + 16],%f12
520 ld [%o0 + globals + 64 + 20],%f13
521 ld [%o0 + globals + 64 + 24],%f14
522 ld [%o0 + globals + 64 + 28],%f15
523 ld [%o0 + globals + 64 + 32],%f16
524 ld [%o0 + globals + 64 + 36],%f17
525 ld [%o0 + globals + 64 + 40],%f18
526 ld [%o0 + globals + 64 + 44],%f19
527 ld [%o0 + globals + 64 + 48],%f20
528 ld [%o0 + globals + 64 + 52],%f21
529 ld [%o0 + globals + 64 + 56],%f22
530 ld [%o0 + globals + 64 + 60],%f23
531 ld [%o0 + globals + 64 + 64],%f24
532 ld [%o0 + globals + 64 + 68],%f25
533 ld [%o0 + globals + 64 + 72],%f26
534 ld [%o0 + globals + 64 + 76],%f27
535 ld [%o0 + globals + 64 + 80],%f28
536 ld [%o0 + globals + 64 + 84],%f29
537 ld [%o0 + globals + 64 + 88],%f30
538 ld [%o0 + globals + 64 + 92],%f31
540 ld [%o0 + globals + 64 + 96],%g1
542 ld [%o0 + globals + 64 + 100],%g1
546 ld [%o0 + globals + 168 + 0],%c0 ! Restore floating-point registers
547 ld [%o0 + globals + 168 + 4],%c1
548 ld [%o0 + globals + 168 + 8],%c2
549 ld [%o0 + globals + 168 + 12],%c3
550 ld [%o0 + globals + 168 + 16],%c4
551 ld [%o0 + globals + 168 + 20],%c5
552 ld [%o0 + globals + 168 + 24],%c6
553 ld [%o0 + globals + 168 + 28],%c7
554 ld [%o0 + globals + 200 + 0],%c8
555 ld [%o0 + globals + 200 + 4],%c9
556 ld [%o0 + globals + 200 + 8],%c10
557 ld [%o0 + globals + 200 + 12],%c11
558 ld [%o0 + globals + 200 + 16],%c12
559 ld [%o0 + globals + 200 + 20],%c13
560 ld [%o0 + globals + 200 + 24],%c14
561 ld [%o0 + globals + 200 + 28],%c15
562 ld [%o0 + globals + 200 + 32],%c16
563 ld [%o0 + globals + 200 + 36],%c17
564 ld [%o0 + globals + 200 + 40],%c18
565 ld [%o0 + globals + 200 + 44],%c19
566 ld [%o0 + globals + 200 + 48],%c20
567 ld [%o0 + globals + 200 + 52],%c21
568 ld [%o0 + globals + 200 + 56],%c22
569 ld [%o0 + globals + 200 + 60],%c23
570 ld [%o0 + globals + 200 + 64],%c24
571 ld [%o0 + globals + 200 + 68],%c25
572 ld [%o0 + globals + 200 + 72],%c26
573 ld [%o0 + globals + 200 + 76],%c27
574 ld [%o0 + globals + 200 + 80],%c28
575 ld [%o0 + globals + 200 + 84],%c29
576 ld [%o0 + globals + 200 + 88],%c30
577 ld [%o0 + globals + 200 + 92],%c31
579 ld [%o0 + globals + 200 + 96],%g1
581 ld [%o0 + globals + 200 + 100],%g1
585 ld [%o0 + globals + 28], %g1 ! Restore global regs back
587 ld [%o0 + globals + 0], %g1
588 ld [%o0 + globals + 4], %g2
589 ld [%o0 + globals + 8], %g3
590 ld [%o0 + globals + 12],%g4
591 ld [%o0 + globals + 16],%g5
592 ld [%o0 + globals + 20],%g6
593 ld [%o0 + globals + 24],%g7
595 /* The following 3 lines are equivalent to: _PRE_Block = 0 */
613 | Information Technology Center
614 | Carnegie-Mellon University
630 | Process assembly language assist for Sailboats.
645 | Stuff to allow saving/restoring registers
650 | savecontext(f, area1, newsp)
651 | int (*f)(); struct savearea *area1; char *newsp;
656 ai sp,sp,-regspace | Save frame pointer & ...
657 | ... allocate space for 16 registers
659 stm r0,0(sp) | Change this if save fewer regs.
660 | Set preemption semaphore
663 putc r6,0(r7) | PRE_Block = 1
664 | r3 = base of savearea
665 put sp,topstack(r3) | area1->topstack = sp
668 be L1 | If newsp == 0, no stack switch
669 cas sp,r4,r0 | Switch to new stack
671 get r6,0(r2) | r2 = _f
677 | struct savearea *area2;
683 | Now in the context of the savecontext stack to be restored.
684 | Start with the registers...
685 | Clear preemption semaphore
688 putc r6,0(r7) | PRE_Block = 0
689 lm r0,0(sp) | Change if saving fewer regs.
690 brx r15 | Return to previous process
699 # Information Technology Center
700 # Carnegie-Mellon University
705 # Process assembly language assist for Sailboats.
722 /*# Offsets of fields*/
725 /*# Stuff to allow saving/restoring registers*/
731 # savecontext(f, area1, newsp)
732 # int (*f)(); struct savearea *area1; char *newsp;
737 ai 1,1,-regspace # Save frame pointer & ...
740 stm 0,0(1) # Change this if save fewer regs.
742 /*# Set preemption semaphore*/
746 /*# r3 = base of savearea*/
747 st 1,topstack(3) # area1->topstack = sp
748 /*# New sp is in r4.*/
750 beq L1 # If newsp == 0, no stack switch
751 cas 1,4,0 # Switch to new stack
764 # struct savearea *area2;
774 # Now in the context of the savecontext stack to be restored.
775 # Start with the registers...
776 # Clear preemption semaphore
782 lm 0,0(1) # Change if saving fewer regs.
783 brx 15 # Return to previous process
790 #endif /* AFS_AIX_ENV */
795 # Information Technology Center
796 # Carnegie-Mellon University
804 # Algorithm: "Monkey see, monkey do"
820 /* Stuff to allow saving/restoring registers */
823 # savecontext(f, area1, newsp)
824 # int (*f)(); struct savearea *area1; char *newsp;
827 /* Stack offsets of arguments */
836 .word 0x0ffc # Save regs R2-R11
837 movb $1,_PRE_Block # Critical section for preemption code
838 pushl ap # save old ap
839 pushl fp # save old fp
840 movl area1(ap),r0 # r0 = base of savearea
841 movl sp,topstack(r0) # area->topstack = sp
842 movl newsp(ap),r0 # Get new sp
843 beql L1 # if new sp is 0, dont change stacks
844 movl r0,sp # else switch to new stack
846 movl f(ap),r1 # r1 = f
849 /* It is impossible to be here, so abort() */
855 # struct savearea *area2;
858 /* Stack offset of argument */
863 .word 0x0 # Who cares about these regs?
864 movl area2(ap),r0 # r0 = address of area2
865 movl topstack(r0),sp # Restore sp
866 movl (sp)+,fp # Restore fp
868 clrb _PRE_Block # End of preemption critical section
871 pushl $1234 # The author will gloat
879 #include <regdef.h> /* Allow use of symbolic names for registers. */
880 /* 9 sregs, ra, 6 fp regs, gp, pad to 8 byte boundary */
881 #define regspace 9 * 4 + 4 + 6 * 8 + 4 + 4
883 #define registers floats + 6 * 8
884 #define returnaddr regspace - 4
886 #define GPOFF regspace - 8
887 .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
888 .ent savecontext /* Insert debugger information. */
891 .cpload t9 # set up gp for KPIC
894 .cprestore GPOFF # trigger t9/jalr
900 .frame sp, regspace, ra
901 /* Save registers. */
902 sw s0, registers + 0(sp)
903 sw s1, registers + 4(sp)
904 sw s2, registers + 8(sp)
905 sw s3, registers + 12(sp)
906 sw s4, registers + 16(sp)
907 sw s5, registers + 20(sp)
908 sw s6, registers + 24(sp)
909 sw s7, registers + 28(sp)
910 sw s8, registers + 32(sp)
911 /* Save return address */
912 sw ra, returnaddr(sp)
914 /* Need to save floating point registers? */
915 s.d $f20, floats + 0(sp)
916 s.d $f22, floats + 8(sp)
917 s.d $f24, floats + 16(sp)
918 s.d $f26, floats + 24(sp)
919 s.d $f28, floats + 32(sp)
920 s.d $f30, floats + 40(sp)
921 .fmask 0x55400000, regspace
923 beq a2, $0, samestack
934 .cpload t9 # set up gp for KPIC
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)
965 /* Code for MIPS R2000/R3000 architecture
966 * Written by Zalman Stern April 30th, 1989.
968 #include <regdef.h> /* Allow use of symbolic names for registers. */
969 #define regspace 9 * 4 + 4 + 6 * 8
971 #define registers floats + 6 * 8
972 #define returnaddr regspace - 4
974 .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
975 .ent savecontext /* Insert debugger information. */
981 .frame sp, regspace, ra
982 /* Save registers. */
983 sw s0, registers + 0(sp)
984 sw s1, registers + 4(sp)
985 sw s2, registers + 8(sp)
986 sw s3, registers + 12(sp)
987 sw s4, registers + 16(sp)
988 sw s5, registers + 20(sp)
989 sw s6, registers + 24(sp)
990 sw s7, registers + 28(sp)
991 sw s8, registers + 32(sp)
992 /* Save return address */
993 sw ra, returnaddr(sp)
995 /* Need to save floating point registers? */
996 s.d $f20, floats + 0(sp)
997 s.d $f22, floats + 8(sp)
998 s.d $f24, floats + 16(sp)
999 s.d $f26, floats + 24(sp)
1000 s.d $f28, floats + 32(sp)
1001 s.d $f30, floats + 40(sp)
1002 .fmask 0x55400000, regspace
1004 beq a2, $0, samestack
1014 lw s0, registers + 0(sp)
1015 lw s1, registers + 4(sp)
1016 lw s2, registers + 8(sp)
1017 lw s3, registers + 12(sp)
1018 lw s4, registers + 16(sp)
1019 lw s5, registers + 20(sp)
1020 lw s6, registers + 24(sp)
1021 lw s7, registers + 28(sp)
1022 lw s8, registers + 32(sp)
1023 /* Save return address */
1024 lw ra, returnaddr(sp)
1025 /* Need to save floating point registers? */
1026 l.d $f20, floats + 0(sp)
1027 l.d $f22, floats + 8(sp)
1028 l.d $f24, floats + 16(sp)
1029 l.d $f26, floats + 24(sp)
1030 l.d $f28, floats + 32(sp)
1031 l.d $f30, floats + 40(sp)
1040 #include "process.s.hpux"
1041 #endif /* AFS_HPUX_ENV */
1044 /* Code for DEC Alpha architecture */
1046 #include <machine/asm.h>
1047 #include <machine/regdef.h>
1056 #elif defined(AFS_XBSD_ENV)
1057 #include <machine/asm.h>
1058 #else /* !OSF && !XBSD */
1059 #include <mach/alpha/asm.h>
1062 #define FRAMESIZE ((8*8)+8+(7*8))
1064 #define registers (floats+(8*8))
1065 #define returnaddr (FRAMESIZE-8)
1073 NESTED(savecontext,FRAMESIZE,ra)
1075 NESTED(savecontext,3,FRAMESIZE,ra,0x0400f700,0x000003fc)
1080 lda sp,-FRAMESIZE(sp)
1081 /* Save callee-saved registers. */
1082 stq s0, (registers+0) (sp)
1083 stq s1, (registers+8) (sp)
1084 stq s2, (registers+16) (sp)
1085 stq s3, (registers+24) (sp)
1086 stq s4, (registers+32) (sp)
1087 stq s5, (registers+40) (sp)
1088 stq s6, (registers+48) (sp)
1089 /* Save return address */
1090 stq ra, returnaddr(sp)
1092 .mask (M_S0|M_S1|M_S2|M_S3|M_S4|M_S5|M_S6|M_RA), -FRAMESIZE
1094 /* Save floating point registers */
1095 stt fs0, (floats+0) (sp)
1096 stt fs1, (floats+8) (sp)
1097 stt fs2, (floats+16) (sp)
1098 stt fs3, (floats+24) (sp)
1099 stt fs4, (floats+32) (sp)
1100 stt fs5, (floats+40) (sp)
1101 stt fs6, (floats+48) (sp)
1102 stt fs7, (floats+56) (sp)
1105 stq sp, topstack(a1)
1106 or a0,zero,pv /* call point in pv */
1108 or a2,zero,sp /* switch stack */
1110 jsr ra,(pv),0 /* off we go */
1121 ldq sp, topstack(a0)
1122 /* Restore callee-saved regs */
1123 ldq s0, (registers+0) (sp)
1124 ldq s1, (registers+8) (sp)
1125 ldq s2, (registers+16) (sp)
1126 ldq s3, (registers+24) (sp)
1127 ldq s4, (registers+32) (sp)
1128 ldq s5, (registers+40) (sp)
1129 ldq s6, (registers+48) (sp)
1130 /* Return address */
1131 ldq ra, returnaddr(sp)
1132 /* Floating point registers */
1133 ldt fs0, (floats+0) (sp)
1134 ldt fs1, (floats+8) (sp)
1135 ldt fs2, (floats+16) (sp)
1136 ldt fs3, (floats+24) (sp)
1137 ldt fs4, (floats+32) (sp)
1138 ldt fs5, (floats+40) (sp)
1139 ldt fs6, (floats+48) (sp)
1140 ldt fs7, (floats+56) (sp)
1141 lda sp, FRAMESIZE(sp)
1149 * 1. Registers R10..R31 and CR0..CR7 are saved
1150 * 2. "struct savearea" must hold at least 3 pointers (long)
1151 * 3. This code will only work on 32 bit machines (601..604), not 620
1152 * 4. No floating point registers are saved
1153 * 5. The save stack "frame" is bigger than absolutely necessary. The
1154 * PowerPC [AIX] ABI needs this extra space.
1158 /* Mach-O assemblers */
1159 #if !defined(NeXT) && !defined(__APPLE__)
1192 #endif /* !NeXT && !__APPLE__ */
1196 * savecontext(int (*f)(), struct savearea *save, char *newsp)
1199 #define FRAME_SIZE (32*4)+(8*4)
1200 #define FRAME_OFFSET (8*4)
1201 #define TOP_OF_STACK (0*4)
1202 #define RETURN (1*4)
1205 #if defined(NeXT) || defined(__APPLE__)
1208 lis r9,ha16(_PRE_Block) /* Disable interrupt fiddling */
1210 stb r8,lo16(_PRE_Block)(r9)
1214 lis r9,PRE_Block@ha /* Disable interrupt fiddling */
1216 stb r8,PRE_Block@l(r9)
1217 #endif /* NeXT || __APPLE__ */
1218 subi r1,r1,FRAME_SIZE
1221 stw r10,10*4+FRAME_OFFSET(r1) /* Save registers */
1222 stw r11,11*4+FRAME_OFFSET(r1)
1223 stw r12,12*4+FRAME_OFFSET(r1)
1224 stw r13,13*4+FRAME_OFFSET(r1)
1225 stw r14,14*4+FRAME_OFFSET(r1)
1226 stw r15,15*4+FRAME_OFFSET(r1)
1227 stw r16,16*4+FRAME_OFFSET(r1)
1228 stw r17,17*4+FRAME_OFFSET(r1)
1229 stw r18,18*4+FRAME_OFFSET(r1)
1230 stw r19,19*4+FRAME_OFFSET(r1)
1231 stw r20,20*4+FRAME_OFFSET(r1)
1232 stw r21,21*4+FRAME_OFFSET(r1)
1233 stw r22,22*4+FRAME_OFFSET(r1)
1234 stw r23,23*4+FRAME_OFFSET(r1)
1235 stw r24,24*4+FRAME_OFFSET(r1)
1236 stw r25,25*4+FRAME_OFFSET(r1)
1237 stw r26,26*4+FRAME_OFFSET(r1)
1238 stw r27,27*4+FRAME_OFFSET(r1)
1239 stw r28,28*4+FRAME_OFFSET(r1)
1240 stw r29,29*4+FRAME_OFFSET(r1)
1241 stw r30,30*4+FRAME_OFFSET(r1)
1242 stw r31,31*4+FRAME_OFFSET(r1)
1243 stw r1,TOP_OF_STACK(r4)
1244 cmpi 0,r5,0 /* New stack specified? */
1248 beq L1 /* No - don't muck with pointer */
1251 L1: blr /* Return */
1254 * returnto(struct savearea *area)
1256 #if defined(NeXT) || defined(__APPLE__)
1262 #endif /* NeXT || __APPLE__ */
1263 lwz r1,TOP_OF_STACK(r3) /* Update stack pointer */
1264 lwz r0,RETURN(r3) /* Get return address */
1268 lwz r10,10*4+FRAME_OFFSET(r1) /* Restore registers */
1269 lwz r11,11*4+FRAME_OFFSET(r1)
1270 lwz r12,12*4+FRAME_OFFSET(r1)
1271 lwz r13,13*4+FRAME_OFFSET(r1)
1272 lwz r14,14*4+FRAME_OFFSET(r1)
1273 lwz r15,15*4+FRAME_OFFSET(r1)
1274 lwz r16,16*4+FRAME_OFFSET(r1)
1275 lwz r17,17*4+FRAME_OFFSET(r1)
1276 lwz r18,18*4+FRAME_OFFSET(r1)
1277 lwz r19,19*4+FRAME_OFFSET(r1)
1278 lwz r20,20*4+FRAME_OFFSET(r1)
1279 lwz r21,21*4+FRAME_OFFSET(r1)
1280 lwz r22,22*4+FRAME_OFFSET(r1)
1281 lwz r23,23*4+FRAME_OFFSET(r1)
1282 lwz r24,24*4+FRAME_OFFSET(r1)
1283 lwz r25,25*4+FRAME_OFFSET(r1)
1284 lwz r26,26*4+FRAME_OFFSET(r1)
1285 lwz r27,27*4+FRAME_OFFSET(r1)
1286 lwz r28,28*4+FRAME_OFFSET(r1)
1287 lwz r29,29*4+FRAME_OFFSET(r1)
1288 lwz r30,30*4+FRAME_OFFSET(r1)
1289 lwz r31,31*4+FRAME_OFFSET(r1)
1290 #if defined(NeXT) || defined(__APPLE__)
1291 lis r9,ha16(_PRE_Block) /* Re-enable interrupt fiddling */
1293 stb r8,lo16(_PRE_Block)(r9)
1295 lis r9,PRE_Block@ha /* Re-enable interrupt fiddling */
1297 stb r8,PRE_Block@l(r9)
1298 #endif /* NeXT || __APPLE__ */
1299 addi r1,r1,FRAME_SIZE
1303 #if defined(__linux__) && defined(__ELF__)
1304 .section .note.GNU-stack,"",%progbits