Standardize License information
[openafs.git] / src / lwp / process.s
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 #define IGNORE_STDS_H   1
11 #include <afs/param.h>
12
13 #if defined(RIOS)
14
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
20  */
21
22
23 /*
24  * savecontext(f, area1, newsp)
25  *     int (*f)(); struct savearea *area1; char *newsp;
26  */
27         .set    topstack, 0
28         .set    cr0, 0
29         .set    toc, 2
30         .set    r0, 0
31         .set    r1, 1
32         .set    r2, 2
33         .set    r3, 3
34         .set    r4, 4
35         .set    r5, 5
36         .set    r6, 6
37         .set    r7, 7
38         .set    r12, 12
39         .set    a_f, r3
40         .set    a_area1, r4
41         .set    a_newsp, r5
42
43         .set    argarea,  32
44         .set    linkarea, 24
45         .set    nfprs,    18
46         .set    ngprs,    20
47         .set    szdsa,    8*nfprs+4*ngprs+linkarea+argarea
48
49         .csect .savecontext[PR]
50         .globl .savecontext[PR]
51
52         mflr    r0                      # save link register
53                 
54 /*
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.
58  */
59         stfd  14, -144(1)
60         stfd  15, -136(1)
61
62         mfcr    r12                     # save CR
63
64         stfd  16, -128(1)
65         stfd  17, -120(1)
66
67         l       11, 0(a_f)              # r11 <- *(a_f)
68
69         stfd  18, -112(1)
70         stfd  19, -104(1)
71
72         cmpi    cr0, a_newsp, 0         # cr0 <- (a_newsp :: 0)
73
74         stfd  20, -96(1)
75         stfd  21, -88(1)
76         stfd  22, -80(1)
77
78         mtlr    11                      # set up lr early so prefetch works
79
80         stfd  23, -72(1)
81         stfd  24, -64(1)
82         stfd  25, -56(1)
83
84         st      r0, 8(r1)               # save return addr
85
86         stfd  26, -48(1)
87         stfd  27, -40(1)
88         stfd  28, -32(1)
89
90         st      12, 4(r1)               # save CR
91
92         stfd  29, -24(1)
93         stfd  30, -16(1)
94         stfd  31, -8(1)
95
96 /*
97  *  save general-purpose registers
98  */
99         stm     12, -8*nfprs-4*ngprs(r1)# save the general-purpose regs
100         stu     r1, -szdsa(r1)          # dec SP and save back chain
101
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
105
106         st      r1, topstack(a_area1)   # save old SP
107         
108         beq    L1                       # if (a_newsp == 0) goto L1
109
110         mr      r1, r5                  # r1 <- a_newsp -- load new SP
111
112 L1:     brl                             # pc <- lr      -- (*a_f)()
113
114 /*
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.
119  */
120         .set    a_area2, r3
121
122         .csect  .returnto[PR]
123         .globl  .returnto[PR]
124
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
128
129         l       8, 8(1)                 # restore lr
130         mtlr    8                       # do it early so prefetch works
131
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
136
137 /*
138  * restore FPRs here!
139  */
140         lfd  14, -144(1)
141         lfd  15, -136(1)
142         lfd  16, -128(1)
143         lfd  17, -120(1)
144         lfd  18, -112(1)
145         lfd  19, -104(1)
146         lfd  20, -96(1)
147         lfd  21, -88(1)
148         lfd  22, -80(1)
149         lfd  23, -72(1)
150         lfd  24, -64(1)
151         lfd  25, -56(1)
152         lfd  26, -48(1)
153         lfd  27, -40(1)
154         lfd  28, -32(1)
155         lfd  29, -24(1)
156         lfd  30, -16(1)
157         lfd  31, -8(1)
158
159         brl                             # pc <- lr      -- return
160
161         .toc
162
163 PRE_Block.S:
164         .tc     PRE_Block[tc], PRE_Block[ua]
165         .extern PRE_Block[ua]
166
167 #endif  /* RIOS */
168
169 #ifdef mc68000
170 /*
171 #
172 #       Information Technology Center
173 #       Carnegie-Mellon University
174 #
175 #
176 */
177         .data
178
179 /*
180 #
181 #       Process assembly language assist for Suns.
182 #
183 */
184
185         .text
186         .even
187
188 /*
189 #
190 # struct savearea {
191 #       char    *topstack;
192 # }
193 #
194 */
195
196         .globl  _PRE_Block
197
198 topstack =      0
199
200 /* Stuff to allow saving/restoring registers */
201 nregs   =       13
202 regs    =       0x3ffe                  | d1-d7 & a0-a5
203
204 /*
205 # savecontext(f, area1, newsp)
206 #     int (*f)(); struct savearea *area1; char *newsp;
207 */
208
209 /* Stack offsets of arguments */
210 f       =       8
211 area1   =       12
212 newsp   =       16
213
214         .globl  _savecontext
215 _savecontext:
216         movb    #1,_PRE_Block           | Dont allow any interrupt finagling
217         link    a6,#-(nregs*4)          | Save frame pointer & ...
218                                         | ... allocate space for nregs registers
219 /* Save registers */
220         moveml  #regs,sp@
221
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
227 forw1:
228         movl    a6@(f),a0               | a0 = f
229         jbsr    a0@                     | f()
230
231 /* It is impossible to be here, so abort() */
232
233         jbsr    _abort
234
235 /*
236 # returnto(area2)
237 #     struct savearea *area2;
238 */
239
240 /* Stack offset of argument */
241 area2   =       8
242
243         .globl _returnto
244 _returnto:
245         link    a6,#0
246         movl    a6@(area2),a0           | Base of savearea
247         movl    a0@(topstack),sp        | Restore sp
248 /* Restore registers */
249         moveml  sp@,#regs
250
251         addl    #(nregs*4),sp
252         movl    sp,a6                   | Argghh...be careful here
253         unlk    a6
254         clrb    _PRE_Block
255         rts                             | Return to previous process
256 #endif /* mc68000 */
257 #ifdef  sparc
258 #ifdef  AFS_SUN5_ENV
259 #define _ASM    1
260 #include        <sys/asm_linkage.h>
261 #include  <sys/trap.h>
262 #else
263 #include        <sun4/asm_linkage.h>
264 #include  <sun4/trap.h>
265 #endif
266         .data   
267 #ifdef  AFS_SUN5_ENV
268         .globl  PRE_Block
269 #else
270         .globl  _PRE_Block
271 #endif
272 topstack        = 0
273 globals = 4
274 /*
275 # savecontext(f, area1, newsp)
276 #     int (*f)(); struct savearea *area1; char *newsp;
277 */
278         .text
279 #ifdef  AFS_SUN5_ENV
280         .globl  savecontext
281 savecontext:
282 #else
283         .globl  _savecontext
284 _savecontext:
285 #endif
286         save    %sp, -SA(MINFRAME), %sp ! Get new window
287         ta      ST_FLUSH_WINDOWS                ! FLush all other active windows
288
289         /* The following 3 lines do the equivalent of: _PRE_Block = 1 */
290 #ifdef  AFS_SUN5_ENV
291         set     PRE_Block, %l0
292 #else
293         set     _PRE_Block, %l0
294 #endif
295         mov     1,%l1
296         stb     %l1, [%l0]
297
298         st      %fp,[%i1+topstack]              ! area1->topstack = sp
299         
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]
307         mov     %y, %g1
308         st      %g1, [%i1 + globals + 28]
309
310 #ifdef  save_allregs
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]
343 #ifdef  notdef
344         mov     %fsr,%g1
345         st      %g1, [%i1 + globals + 64 + 96]
346         mov     %fq,%g1
347         st      %g1, [%i1 + globals + 64 + 100]
348 #endif
349
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]
382 #ifdef  notdef
383         mov     %csr,%g1
384         st      %g1, [%i1 + globals + 200 + 96]
385         mov     %cq,%g1
386         st      %g1, [%i1 + globals + 200 + 100]
387 #endif
388 #endif
389         cmp     %i2, 0
390         be,a    L1                              ! if (newsp == 0) no stack switch
391         nop
392 #ifdef  notdef
393         add     %i2, STACK_ALIGN - 1, %i2
394         and     %i2, ~(STACK_ALIGN - 1), %i2
395         sub     %i2, SA(MINFRAME), %fp
396         call    %i0
397         restore
398 #else
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.
405         restore
406         add     %o2, STACK_ALIGN - 1, %o2
407         and     %o2, ~(STACK_ALIGN - 1), %o2    
408         call    %o0
409         sub     %o2, SA(MINFRAME), %sp
410 #endif  
411
412 L1:     call    %i0                     ! call f()
413         nop
414
415
416 ! returnto(area1)
417 !     struct savearea *area1;
418 #ifdef  AFS_SUN5_ENV
419         .globl returnto
420 returnto:
421 #else
422         .globl _returnto
423 _returnto:
424 #endif
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
429
430 #ifdef  save_allregs
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
463 #ifdef  notdef
464         ld      [%o0 + globals + 64 + 96],%g1
465         mov     %g1, %fsr
466         ld      [%o0 + globals + 64 + 100],%g1
467         mov     %g1, %fq
468 #endif
469
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
502 #ifdef  notdef
503         ld      [%o0 + globals + 200 + 96],%g1
504         mov     %g1, %csr
505         ld      [%o0 + globals + 200 + 100],%g1
506         mov     %g1, %cq
507 #endif
508 #endif
509         ld      [%o0 + globals + 28], %g1               ! Restore global regs back
510         mov     %g1, %y
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
518
519         /* The following 3 lines are equivalent to: _PRE_Block = 0 */
520 #ifdef  AFS_SUN5_ENV
521         set     PRE_Block, %l0
522 #else
523         set     _PRE_Block, %l0
524 #endif
525         mov     0,%l1
526         stb     %l1, [%l0]
527
528         restore                                 
529         restore
530
531         retl
532         nop
533
534 #endif /* sparc */
535 #ifdef ibm032
536 |
537 |       Information Technology Center
538 |       Carnegie-Mellon University
539 |
540 |
541         .data
542         .globl  .oVncs
543         .set            .oVncs,0
544
545         .globl  _savecontext
546 _savecontext:
547         .long           _.savecontext
548
549         .globl  _returnto
550 _returnto:
551         .long           _.returnto
552
553 |
554 |       Process assembly language assist for Sailboats.
555 |
556
557         .text
558         .align 2
559
560 |
561 | struct savearea {
562 |       char    *topstack;
563 | }
564 |
565
566 | Offsets of fields
567 .set topstack,0
568
569 | Stuff to allow saving/restoring registers
570 .set regspace,64
571 .set freg,0
572
573 |
574 | savecontext(f, area1, newsp)
575 |    int (*f)(); struct savearea *area1; char *newsp;
576 |
577
578         .globl  _.savecontext
579 _.savecontext:
580         ai      sp,sp,-regspace         | Save frame pointer & ...
581                                         | ... allocate space for 16 registers
582 | Save registers
583         stm     r0,0(sp)                        | Change this if save fewer regs.
584 | Set preemption semaphore
585         get     r6,$1
586         get     r7,$_PRE_Block
587         putc    r6,0(r7)                        | PRE_Block = 1
588 | r3 = base of savearea
589         put     sp,topstack(r3)         | area1->topstack = sp
590 | New sp is in r4.
591         cis     r4,0
592         be      L1                      | If newsp == 0, no stack switch
593         cas     sp,r4,r0                        | Switch to new stack
594 L1:
595         get     r6,0(r2)                        | r2 = _f
596         balrx   r15,r6                  | f()
597         cas     r0,r2,r0
598
599 |
600 | returnto(area2)
601 |     struct savearea *area2;
602 |
603
604         .globl _.returnto
605 _.returnto:
606         get     sp,topstack(r2)
607 | Now in the context of the savecontext stack to be restored.
608 | Start with the registers...
609 | Clear preemption semaphore
610         get     r6,$0
611         get     r7,$_PRE_Block
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
615         ai      sp,sp,regspace
616  .data
617  .ltorg
618 #endif
619
620 #ifdef AFS_AIX22_ENV
621 /*
622 #
623 #       Information Technology Center
624 #       Carnegie-Mellon University
625 #
626 */
627 /*
628 #
629 #       Process assembly language assist for Sailboats.
630 #
631 */
632
633         .text
634         .globl  .savecontext
635         .align 1
636
637 /*
638 #
639 # struct savearea {
640 #       char    *topstack;
641 # }
642 #
643 */
644
645
646 /*# Offsets of fields*/
647 .set topstack,0
648
649 /*# Stuff to allow saving/restoring registers*/
650 .set regspace,64
651 .set freg,0
652
653 /*
654 #
655 # savecontext(f, area1, newsp)
656 #    int (*f)(); struct savearea *area1; char *newsp;
657 #
658 */
659
660 .savecontext:
661         ai      1,1,-regspace           # Save frame pointer & ...
662
663 /*# Save registers*/
664         stm     0,0(1)                  # Change this if save fewer regs.
665         lr      14,0
666 /*# Set preemption semaphore*/
667         lis     6,1
668         l       7,4(14)
669         stc     6,0(7)
670 /*# r3 = base of savearea*/
671         st      1,topstack(3)           # area1->topstack = sp
672 /*# New sp is in r4.*/
673         ci      4,0
674         beq     L1                      # If newsp == 0, no stack switch
675         cas     1,4,0                   # Switch to new stack
676 L1:
677         l       6,0(2)                  # r2 = _f
678         balrx   15,6                    # f()
679         cas     0,2,0
680         .data   3
681         .globl  _savecontext
682 _savecontext:
683         .long   .savecontext
684         .long   _PRE_Block
685 /*
686 #
687 # returnto(area2)
688 #     struct savearea *area2;
689 #
690 */
691
692         .text
693         .globl  .returnto
694         .align 1
695 .returnto:
696         l       1,topstack(2)
697 /*
698 # Now in the context of the savecontext stack to be restored.
699 # Start with the registers...
700 # Clear preemption semaphore
701 */
702         lr      14,0
703         lis     6,0
704         l       7,4(14)
705         stc     6,0(7)
706         lm      0,0(1)          # Change if saving fewer regs.
707         brx     15              # Return to previous process
708         ai      1,1,regspace
709         .data   3
710         .globl  _returnto
711 _returnto:
712         .long   .returnto
713         .long   _PRE_Block
714 #endif /* AFS_AIX_ENV */
715
716 #ifdef vax
717 /*
718 #
719 #       Information Technology Center
720 #       Carnegie-Mellon University
721 #
722 #
723 */
724         .data
725
726 /*
727 #
728 #       Algorithm: "Monkey see, monkey do"
729 #
730 */
731
732         .text
733
734 /*
735 #
736 # struct savearea {
737 #       char    *topstack;
738 # }
739 #
740 */
741
742         .set    topstack,0
743
744 /* Stuff to allow saving/restoring registers */
745
746 /*
747 # savecontext(f, area1, newsp)
748 #     int (*f)(); struct savearea *area1; char *newsp;
749 */
750
751 /* Stack offsets of arguments */
752         .set    f,4
753         .set    area1,8
754         .set    newsp,12
755
756 .globl  _PRE_Block
757 .globl  _savecontext
758
759 _savecontext:
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
769 L1:
770         movl    f(ap),r1                # r1 = f
771         calls   $0,0(r1)                # f()
772
773 /* It is impossible to be here, so abort() */
774
775         calls   $0,_abort
776
777 /*
778 # returnto(area2)
779 #     struct savearea *area2;
780 */
781
782 /* Stack offset of argument */
783         .set    area2,4
784
785         .globl _returnto
786 _returnto:
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
791         movl    (sp)+,ap                # ,,,,
792         clrb    _PRE_Block              # End of preemption critical section
793         ret
794
795         pushl   $1234                   # The author will gloat
796         calls   $0,_abort
797 #endif
798
799 #ifdef mips
800 #ifdef  sgi
801         .option pic2
802
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
806 #define floats 0
807 #define registers floats + 6 * 8
808 #define returnaddr regspace - 4
809 #define topstack 0
810 #define GPOFF   regspace - 8
811         .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
812         .ent savecontext /* Insert debugger information. */
813 savecontext:
814         .set    noreorder
815         .cpload t9                      # set up gp for KPIC
816         .set    reorder
817         subu sp, regspace
818         .cprestore GPOFF                # trigger t9/jalr
819         .set    noreorder
820         li      t0, 1
821         .extern PRE_Block
822         sb      t0, PRE_Block
823         .set    reorder
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)
837         .mask   0xc0ff0000, -4
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
846         sw      sp, topstack(a1)
847         beq     a2, $0, samestack
848         move    sp, a2
849 samestack:
850         move    t9, a0
851         j       t9
852         .end    savecontext
853
854         .globl  returnto
855         .ent    returnto
856 returnto:
857         .set    noreorder
858         .cpload t9                      # set up gp for KPIC
859         .set    reorder
860
861         lw      sp, topstack(a0)
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)
880         .set    noreorder
881         addu    sp, regspace
882         la      t0, PRE_Block
883         j       ra
884         sb      zero, 0(t0)
885         .set    reorder
886         .end    returnto
887
888 #else
889 /* Code for MIPS R2000/R3000 architecture
890  * Written by Zalman Stern April 30th, 1989.
891  */
892 #include <regdef.h> /* Allow use of symbolic names for registers. */
893 #define regspace 9 * 4 + 4 + 6 * 8
894 #define floats 0
895 #define registers floats + 6 * 8
896 #define returnaddr regspace - 4
897 #define topstack 0
898         .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
899         .ent savecontext /* Insert debugger information. */
900 savecontext:
901         li      t0, 1
902         .extern PRE_Block
903         sb      t0, PRE_Block
904         subu    sp, regspace
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)
918         .mask   0xc0ff0000, -4
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
927         sw      sp, topstack(a1)
928         beq     a2, $0, samestack
929         addu    sp, $0, a2
930 samestack:
931         jal     a0
932         .end    savecontext
933
934         .globl  returnto
935         .ent    returnto
936 returnto:
937         lw      sp, topstack(a0)
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)
956         addu    sp, regspace
957         sb      $0, PRE_Block
958         j       ra
959         .end    returnto
960 #endif  /* sgi */
961 #endif
962
963 #ifdef AFS_HPUX_ENV
964 #include "process.s.hpux"
965 #endif /* AFS_HPUX_ENV */
966
967 #ifdef __alpha
968 /* Code for DEC Alpha architecture */
969 #ifdef  AFS_OSF_ENV
970 #include <machine/asm.h>
971 #include <machine/regdef.h>
972 #define fs0     $f2
973 #define fs1     $f3
974 #define fs2     $f4
975 #define fs3     $f5
976 #define fs4     $f6
977 #define fs5     $f7
978 #define fs6     $f8
979 #define fs7     $f9
980 #else   /* OSF */
981 #include <mach/alpha/asm.h>
982 #endif  /* OSF */
983
984 #define FRAMESIZE ((8*8)+8+(7*8))
985 #define floats 0
986 #define registers (floats+(8*8))
987 #define returnaddr (FRAMESIZE-8)
988 #define topstack 0
989
990 IMPORT(PRE_Block,4)
991 .align  4
992 #ifdef  AFS_OSF_ENV
993 NESTED(savecontext,FRAMESIZE,ra)
994 #else   /* OSF */
995 NESTED(savecontext,3,FRAMESIZE,ra,0x0400f700,0x000003fc)
996 #endif  /* OSF */
997         ldgp    gp,0(pv)
998         lda     t0, 1(zero)
999         stl     t0, PRE_Block
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)
1011
1012         .mask   (M_S0|M_S1|M_S2|M_S3|M_S4|M_S5|M_S6|M_RA), -FRAMESIZE
1013
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)
1023
1024         .prologue       1
1025         stq     sp, topstack(a1)
1026         or      a0,zero,pv              /* call point in pv */
1027         beq     a2, samestack
1028         or      a2,zero,sp              /* switch stack */
1029 samestack:
1030         jsr     ra,(pv),0               /* off we go */
1031         END(savecontext)
1032
1033 #ifdef  AFS_OSF_ENV
1034 LEAF(returnto)
1035 #else   
1036 LEAF(returnto,1)
1037 #endif  
1038         ldgp    gp,0(pv)
1039
1040         .prologue       1
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)
1062         stl     zero, PRE_Block
1063         RET
1064         END(returnto)
1065 #endif
1066
1067 #if defined(AFS_NCR_ENV) || defined(AFS_X86_ENV)
1068 /* Sun 386i... I hope this does the right thing!!!
1069  * 
1070  * Written by Derek Atkins <warlord@MIT.EDU>
1071  * (debugging help by Chris Provenzano <proven@mit.edu>)
1072  * 11/1991
1073  *
1074  * "ojala que es correcto!"
1075  */
1076         .file "process.s"
1077
1078         .data
1079
1080         .text
1081
1082 /*
1083  * struct savearea {
1084  *      char    *topstack;
1085  * }
1086  */
1087
1088         .set    topstack,0
1089
1090 /*
1091  * savecontext(f, area1, newsp)
1092  *      int (*f)(); struct savearea *area1; char *newsp;
1093  */
1094
1095 /* offsets, to make my life easier! */
1096         .set    f,8
1097         .set    area1,12
1098         .set    newsp,16
1099
1100
1101 .globl  PRE_Block
1102 .globl  savecontext
1103
1104 savecontext:
1105         pushl   %ebp                    /* New Frame! */
1106         movl    %esp,%ebp
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 */
1112         cmpl    $0,%eax
1113         je      L1                      /* if new sp is 0 then dont change esp */
1114         movl    %eax,%esp               /* go ahead.  make my day! */
1115 L1:
1116         jmp     *f(%ebp)                        /* ebx = &f */
1117
1118 /* Shouldnt be here....*/
1119
1120         call    abort
1121
1122 /*
1123  * returnto(area2)
1124  *      struct savearea *area2;
1125  */
1126
1127 /* stack offset */
1128         .set    area2,8
1129
1130 .globl  returnto
1131
1132 returnto:
1133         pushl   %ebp
1134         movl    %esp, %ebp              /* New frame, to get correct pointer */
1135         movl    area2(%ebp),%eax        /* eax = area2 */
1136         movl    (%eax),%esp             /* restore esp */
1137         popa 
1138         movl    $0,PRE_Block            /* clear it up... */
1139         popl    %ebp
1140         ret
1141
1142 /* I see, said the blind man, as he picked up his hammer and saw! */
1143         pushl   $1234
1144         call    abort
1145
1146
1147 #endif /* AFS_NCR_ENV */
1148