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