Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / lwp / process.s.hpux
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
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
8 */
9
10 #ifdef AFS_HPUX_ENV
11 #ifdef hp9000s300
12 /*
13 #
14 # Process assembly language assist for HP 9000 series 300s.
15 #
16 */
17
18 text
19
20 /*
21 #
22 # struct savearea {
23 # char *topstack;
24 # }
25 #
26 */
27
28 global _PRE_Block
29
30 set topstack,0
31
32 /* Stuff to allow saving/restoring registers */
33 set NREGS,13
34 set REGS,0x3ffe # d1-d7 & a0-a5
35
36 /*
37 # savecontext(f, area1, newsp)
38 # int (*f)(); struct savearea *area1; char *newsp;
39 */
40
41 /* Stack offsets of arguments */
42 set f,8
43 set area1,12
44 set newsp,16
45
46 global _savecontext
47 _savecontext:
48 mov.b &1,_PRE_Block # Dont allow any interrupt finagling
49 link %a6,&-(NREGS*4) # Save frame pointer & ...
50 # ... allocate space for nregs registers
51 /* Save registers */
52 movem.l &REGS,(%sp)
53
54 mov.l area1(%a6),%a0 # a0 = base of savearea
55 mov.l %sp,topstack(%a0) # area->topstack = sp
56 mov.l newsp(%a6),%d0 # Get new sp
57 beq.b l1 # If newsp == 0, no stack switch
58 mov.l %d0,%sp # Switch to new stack
59 l1:
60 mov.l f(%a6),%a0 # a0 = f
61 jsr (%a0) # f()
62
63 /* It is impossible to be here, so abort() */
64
65 jsr _abort
66
67 /*
68 # returnto(area2)
69 # struct savearea *area2;
70 */
71
72 /* Stack offset of argument */
73 set area2,8
74
75 global _returnto
76 _returnto:
77 link %a6,&0
78 mov.l area2(%a6),%a0 # Base of savearea
79 mov.l topstack(%a0),%sp # Restore sp
80 /* Restore registers */
81 movem.l (%sp),&REGS
82
83 add.l &(NREGS*4),%sp
84 mov.l %sp,%a6 # Argghh...be careful here
85 unlk %a6
86 clr.b _PRE_Block
87 rts # Return to previous process
88 #else
89
90 .CODE
91
92 ;
93 ; savecontext(f, area1, newsp)
94 ; int (*f)();
95 ; struct savearea *area1;
96 ; char *newsp;
97 ;
98 savecontext
99 .PROC
100 ;
101 ; Callinfo sets up register saves using the ENTRY_GR
102 ; and ENTRY_FR parameters. ENTRY_FR=21 is only valid
103 ; for PA 1.1. (How to deal with this for 800?)
104 ;
105 .CALLINFO CALLER,FRAME=0,SAVE_RP,ENTRY_GR=18,ENTRY_FR=21
106 ; The ENTER statement generates register saves and
107 ; procedure setup.
108 .ENTER
109
110 LDI 1,%r31 ; Store a (char) 1 in
111 ADDIL LR'PRE_Block-$global$,%r27 ; global variable
112 STB %r31,RR'PRE_Block-$global$(0,%r1) ; PRE_Block.
113
114 COPY %r26,%r22 ; Copy arg0 (f) to dyncall's input register.
115
116 COMIB,= 0,%r24,L$0001 ; Compare arg2 (newsp) to 0. Execute the
117 ; next instruction regardless of value.
118 STWS %r30,0(0,%r25) ; Store the stack pointer in the first
119 ; element (0th offset) of arg1 (area1).
120 COPY %r24,%r30 ; Move arg2 (newsp) into the stack ptr.
121
122 L$0001
123 .CALL
124 BL $$dyncall,%r31 ; Dynamic call using pointer in r22.
125 COPY %r31,%r2
126
127 .CALL
128 BL abort,%r2 ; Can't get here, so abort.
129 NOP
130 .LEAVE
131 .PROCEND
132
133 ; returnto(area2)
134 ; struct savearea *area2;
135 ;
136 returnto
137 .PROC
138 .CALLINFO CALLER,FRAME=0,SAVE_RP,ENTRY_GR=18,ENTRY_FR=21
139 ; No ENTRY is used since this is a magic routine.
140 ADDIL LR'PRE_Block-$global$,%r27 ; PRE_Block = 0
141 STB %r0,RR'PRE_Block-$global$(0,%r1)
142
143 LDWS 0(0,%r26),%r30 ; Load the stack pointer from area2
144 .LEAVE
145 .PROCEND
146
147 .EXPORT savecontext,ENTRY
148 .EXPORT returnto,ENTRY
149 .IMPORT $global$,DATA
150 .IMPORT PRE_Block,DATA
151 .IMPORT $$dyncall,MILLICODE
152 .IMPORT abort,CODE
153
154 .END
155 #endif /* hp9000s300 */
156 #endif /* AFS_HPUX_ENV */