/* $arla: process.rios.S,v 1.1 2000/01/02 02:11:19 lha Exp $ */ /* **************************************************************************** * Copyright IBM Corporation 1988, 1989 - All Rights Reserved * * * * Permission to use, copy, modify, and distribute this software and its * * documentation for any purpose and without fee is hereby granted, * * provided that the above copyright notice appear in all copies and * * that both that copyright notice and this permission notice appear in * * supporting documentation, and that the name of IBM not be used in * * advertising or publicity pertaining to distribution of the software * * without specific, written prior permission. * * * * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM * * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY * * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER * * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * **************************************************************************** */ #include #undef RCSID /* lws 92.11.18 I don't know if we have to save the TOC (R2) or not... * Note that stack-frame is supposed to be aligned on * a double-word boundary. * For details about RIOS calling conventions * see the Assembler manual and /usr/include/sys/asdef.s */ /* * savecontext(f, area1, newsp) * int (*f)(); struct savearea *area1; char *newsp; */ .set topstack, 0 .set cr0, 0 .set toc, 2 .set r0, 0 .set r1, 1 .set r2, 2 .set r3, 3 .set r4, 4 .set r5, 5 .set r6, 6 .set r7, 7 .set r12, 12 .set a_f, r3 .set a_area1, r4 .set a_newsp, r5 .set argarea, 32 .set linkarea, 24 .set nfprs, 18 .set ngprs, 20 .set szdsa, 8*nfprs+4*ngprs+linkarea+argarea .csect .savecontext[PR] .globl .savecontext[PR] mflr r0 # save link register /* * save floating point registers. Interleave some other stuff for * timing reasons. Set up conditions and registers for branches * early, so that processor can prefetch instructions. */ stfd 14, -144(1) stfd 15, -136(1) mfcr r12 # save CR stfd 16, -128(1) stfd 17, -120(1) l 11, 0(a_f) # r11 <- *(a_f) stfd 18, -112(1) stfd 19, -104(1) cmpi cr0, a_newsp, 0 # cr0 <- (a_newsp :: 0) stfd 20, -96(1) stfd 21, -88(1) stfd 22, -80(1) mtlr 11 # set up lr early so prefetch works stfd 23, -72(1) stfd 24, -64(1) stfd 25, -56(1) st r0, 8(r1) # save return addr stfd 26, -48(1) stfd 27, -40(1) stfd 28, -32(1) st 12, 4(r1) # save CR stfd 29, -24(1) stfd 30, -16(1) stfd 31, -8(1) /* * save general-purpose registers */ stm 12, -8*nfprs-4*ngprs(r1)# save the general-purpose regs stu r1, -szdsa(r1) # dec SP and save back chain l r7, PRE_Block.S(toc) # r7 <- &PRE_Block cal r6, 1(r0) # r6 <- #1 st r6, 0(r7) # r6 -> PRE_Block st r1, topstack(a_area1) # save old SP beq L1 # if (a_newsp == 0) goto L1 mr r1, r5 # r1 <- a_newsp -- load new SP L1: brl # pc <- lr -- (*a_f)() /* * returnto(area2) This is a little jumbled, I tried to interleave * memory accesses with simple instructions for speed, and I tried to * set up the link register and condition register reasonably early * so that processor instruction prefetching might help us out a little. */ .set a_area2, r3 .csect .returnto[PR] .globl .returnto[PR] l r1, topstack(a_area2) # r1 <- a_area2->topstack cal r1, szdsa(r1) # pop off frame l r7, PRE_Block.S(toc) # r7 <- &PRE_Block l 8, 8(1) # restore lr mtlr 8 # do it early so prefetch works lm 12, -8*nfprs-4*ngprs(r1) cal r6, 0(r0) # r6 <- #0 mtcrf 0x38, 12 # put back cr st r6, 0(r7) # r6 -> PRE_Block /* * restore FPRs here! */ lfd 14, -144(1) lfd 15, -136(1) lfd 16, -128(1) lfd 17, -120(1) lfd 18, -112(1) lfd 19, -104(1) lfd 20, -96(1) lfd 21, -88(1) lfd 22, -80(1) lfd 23, -72(1) lfd 24, -64(1) lfd 25, -56(1) lfd 26, -48(1) lfd 27, -40(1) lfd 28, -32(1) lfd 29, -24(1) lfd 30, -16(1) lfd 31, -8(1) brl # pc <- lr -- return .toc PRE_Block.S: .tc PRE_Block[tc], PRE_Block[ua] .extern PRE_Block[ua]