5d26c8779b67b4739c654f820dd57593fd6ca98f
[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(__arm32__) || defined(__arm__)
14        /* register definitions */
15        fp      .req    r11
16        ip      .req    r12
17        sp      .req    r13
18        lp      .req    r14
19        pc      .req    r15
20        
21        /*
22           savecontext(f, area1, newsp)
23                int (*f)()#if defined(RIOS);
24                struct savearea *area1;
25                char *newsp;
26        */
27
28        /* Arguments appear as:     f in r0, area1 in r1, newsp in r2 */
29
30        .text
31        .align  0
32        .globl  savecontext
33        .type   savecontext, #function
34 savecontext:
35        @ build the frame
36        mov     ip, sp
37        stmfd   sp!, {fp, ip, lr, pc}
38        sub     fp, ip, #4
39        @ stack r0 - r10, current fp
40        stmfd   sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, fp}
41        str     sp, [r1, #0]
42        @ check if newsp is zero
43        movs    r2, r2
44        movne   sp, r2
45        @ call function ...
46        mov     pc, r0
47
48        /*      should never get here ... */
49        /*      bl      EXT(abort) */
50
51        /*
52          returnto(area2)
53             struct savearea *area2;
54        */
55
56        /* area2 is in r0. */
57
58        .globl returnto
59        .type  returnto, #function
60 returnto:
61        @ restore r0-r10, fp
62        ldr     r0, [r0, #0]
63        ldmfd   r0, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, fp}
64        @ return from function call
65        ldmea   fp, {fp, sp, pc}
66
67 #endif /* __arm32__ or __arm__ */
68
69 #if defined(RIOS)
70 /*                 I don't know if we have to save the TOC (R2) or not...
71  *                 Note that stack-frame is supposed to be aligned on 
72  *                 a double-word boundary.
73  *                 For details about RIOS calling conventions
74  *                 see the Assembler manual and /usr/include/sys/asdef.s
75  */
76
77
78 /*
79  * savecontext(f, area1, newsp)
80  *     int (*f)(); struct savearea *area1; char *newsp;
81  */
82         .set    topstack, 0
83         .set    cr0, 0
84         .set    toc, 2
85         .set    r0, 0
86         .set    r1, 1
87         .set    r2, 2
88         .set    r3, 3
89         .set    r4, 4
90         .set    r5, 5
91         .set    r6, 6
92         .set    r7, 7
93         .set    r12, 12
94         .set    a_f, r3
95         .set    a_area1, r4
96         .set    a_newsp, r5
97
98         .set    argarea,  32
99         .set    linkarea, 24
100         .set    nfprs,    18
101         .set    ngprs,    20
102         .set    szdsa,    8*nfprs+4*ngprs+linkarea+argarea
103
104         .csect .savecontext[PR]
105         .globl .savecontext[PR]
106
107         mflr    r0                      # save link register
108                 
109 /*
110  *  save floating point registers.  Interleave some other stuff for
111  *  timing reasons.  Set up conditions and registers for branches
112  *  early, so that processor can prefetch instructions.
113  */
114         stfd  14, -144(1)
115         stfd  15, -136(1)
116
117         mfcr    r12                     # save CR
118
119         stfd  16, -128(1)
120         stfd  17, -120(1)
121
122         l       11, 0(a_f)              # r11 <- *(a_f)
123
124         stfd  18, -112(1)
125         stfd  19, -104(1)
126
127         cmpi    cr0, a_newsp, 0         # cr0 <- (a_newsp :: 0)
128
129         stfd  20, -96(1)
130         stfd  21, -88(1)
131         stfd  22, -80(1)
132
133         mtlr    11                      # set up lr early so prefetch works
134
135         stfd  23, -72(1)
136         stfd  24, -64(1)
137         stfd  25, -56(1)
138
139         st      r0, 8(r1)               # save return addr
140
141         stfd  26, -48(1)
142         stfd  27, -40(1)
143         stfd  28, -32(1)
144
145         st      12, 4(r1)               # save CR
146
147         stfd  29, -24(1)
148         stfd  30, -16(1)
149         stfd  31, -8(1)
150
151 /*
152  *  save general-purpose registers
153  */
154         stm     12, -8*nfprs-4*ngprs(r1)# save the general-purpose regs
155         stu     r1, -szdsa(r1)          # dec SP and save back chain
156
157         l       r7,  PRE_Block.S(toc)   # r7 <- &PRE_Block
158         cal     r6, 1(r0)               # r6 <- #1
159         stb     r6, 0(r7)               # r6 -> PRE_Block
160
161         st      r1, topstack(a_area1)   # save old SP
162         
163         beq    L1                       # if (a_newsp == 0) goto L1
164
165         mr      r1, r5                  # r1 <- a_newsp -- load new SP
166
167 L1:     brl                             # pc <- lr      -- (*a_f)()
168
169 /*
170  * returnto(area2)   This is a little jumbled, I tried to interleave 
171  * memory accesses with simple instructions for speed, and I tried to 
172  * set up the link register and condition register reasonably early
173  * so that processor instruction prefetching might help us out a little.
174  */
175         .set    a_area2, r3
176
177         .csect  .returnto[PR]
178         .globl  .returnto[PR]
179
180         l       r1, topstack(a_area2)   # r1 <- a_area2->topstack
181         cal     r1,  szdsa(r1)          # pop off frame
182         l       r7, PRE_Block.S(toc)    # r7 <- &PRE_Block
183
184         l       8, 8(1)                 # restore lr
185         mtlr    8                       # do it early so prefetch works
186
187         lm      12,  -8*nfprs-4*ngprs(r1)
188         cal     r6, 0(r0)               # r6 <- #0
189         mtcrf   0x38, 12                # put back cr
190         stb     r6, 0(r7)               # r6 -> PRE_Block
191
192 /*
193  * restore FPRs here!
194  */
195         lfd  14, -144(1)
196         lfd  15, -136(1)
197         lfd  16, -128(1)
198         lfd  17, -120(1)
199         lfd  18, -112(1)
200         lfd  19, -104(1)
201         lfd  20, -96(1)
202         lfd  21, -88(1)
203         lfd  22, -80(1)
204         lfd  23, -72(1)
205         lfd  24, -64(1)
206         lfd  25, -56(1)
207         lfd  26, -48(1)
208         lfd  27, -40(1)
209         lfd  28, -32(1)
210         lfd  29, -24(1)
211         lfd  30, -16(1)
212         lfd  31, -8(1)
213
214         brl                             # pc <- lr      -- return
215
216         .toc
217
218 PRE_Block.S:
219         .tc     PRE_Block[tc], PRE_Block[ua]
220         .extern PRE_Block[ua]
221
222 #endif  /* RIOS */
223         
224 #ifdef mc68000
225 /*
226 #
227 #       Information Technology Center
228 #       Carnegie-Mellon University
229 #
230 #
231 */
232         .data
233
234 /*
235 #
236 #       Process assembly language assist for Suns.
237 #
238 */
239
240         .text
241         .even
242
243 /*
244 #
245 # struct savearea {
246 #       char    *topstack;
247 # }
248 #
249 */
250
251         .globl  _PRE_Block
252
253 topstack =      0
254
255 /* Stuff to allow saving/restoring registers */
256 nregs   =       13
257 regs    =       0x3ffe                  | d1-d7 & a0-a5
258
259 /*
260 # savecontext(f, area1, newsp)
261 #     int (*f)(); struct savearea *area1; char *newsp;
262 */
263
264 /* Stack offsets of arguments */
265 f       =       8
266 area1   =       12
267 newsp   =       16
268
269         .globl  _savecontext
270 _savecontext:
271         movb    #1,_PRE_Block           | Dont allow any interrupt finagling
272         link    a6,#-(nregs*4)          | Save frame pointer & ...
273                                         | ... allocate space for nregs registers
274 /* Save registers */
275         moveml  #regs,sp@
276
277         movl    a6@(area1),a0           | a0 = base of savearea
278         movl    sp,a0@(topstack)        | area->topstack = sp
279         movl    a6@(newsp),d0           | Get new sp
280         jeq     forw1                   | If newsp == 0, no stack switch
281         movl    d0,sp                   | Switch to new stack
282 forw1:
283         movl    a6@(f),a0               | a0 = f
284         jbsr    a0@                     | f()
285
286 /* It is impossible to be here, so abort() */
287
288         jbsr    _abort
289
290 /*
291 # returnto(area2)
292 #     struct savearea *area2;
293 */
294
295 /* Stack offset of argument */
296 area2   =       8
297
298         .globl _returnto
299 _returnto:
300         link    a6,#0
301         movl    a6@(area2),a0           | Base of savearea
302         movl    a0@(topstack),sp        | Restore sp
303 /* Restore registers */
304         moveml  sp@,#regs
305
306         addl    #(nregs*4),sp
307         movl    sp,a6                   | Argghh...be careful here
308         unlk    a6
309         clrb    _PRE_Block
310         rts                             | Return to previous process
311 #endif /* mc68000 */
312 #ifdef  sparc
313 #ifdef  AFS_SUN5_ENV
314 #define _ASM    1
315 #include        <sys/asm_linkage.h>
316 #include  <sys/trap.h>
317 #else
318 #ifdef AFS_XBSD_ENV
319 #include <machine/trap.h>
320 #define ST_FLUSH_WINDOWS ST_FLUSHWIN
321 #define MINFRAME 92
322 #define SA(x) (((x)+7)&~7)
323 #define STACK_ALIGN 8
324 #else /* SunOS 4: */
325 #include        <sun4/asm_linkage.h>
326 #include  <sun4/trap.h>
327 #endif
328 #endif
329         .data   
330 #ifdef  AFS_SUN5_ENV
331         .globl  PRE_Block
332 #else
333         .globl  _PRE_Block
334 #endif
335 topstack        = 0
336 globals = 4
337 /*
338 # savecontext(f, area1, newsp)
339 #     int (*f)(); struct savearea *area1; char *newsp;
340 */
341         .text
342 #ifdef  AFS_SUN5_ENV
343         .globl  savecontext
344 savecontext:
345 #else
346         .globl  _savecontext
347 _savecontext:
348 #endif
349         save    %sp, -SA(MINFRAME), %sp ! Get new window
350         ta      ST_FLUSH_WINDOWS                ! FLush all other active windows
351
352         /* The following 3 lines do the equivalent of: _PRE_Block = 1 */
353 #ifdef  AFS_SUN5_ENV
354         set     PRE_Block, %l0
355 #else
356         set     _PRE_Block, %l0
357 #endif
358         mov     1,%l1
359         stb     %l1, [%l0]
360
361         st      %fp,[%i1+topstack]              ! area1->topstack = sp
362         
363         st      %g1, [%i1 + globals + 0]                /* Save all globals just in case */
364         st      %g2, [%i1 + globals + 4]
365         st      %g3, [%i1 + globals + 8]
366         st      %g4, [%i1 + globals + 12]
367         st      %g5, [%i1 + globals + 16]
368         st      %g6, [%i1 + globals + 20]
369         st      %g7, [%i1 + globals + 24]
370         mov     %y, %g1
371         st      %g1, [%i1 + globals + 28]
372
373 #ifdef  save_allregs
374         st      %f0, [%i1 + globals + 32 + 0]           ! Save all floating point registers 
375         st      %f1, [%i1 + globals + 32 + 4]
376         st      %f2, [%i1 + globals + 32 + 8]
377         st      %f3, [%i1 + globals + 32 + 12]
378         st      %f4, [%i1 + globals + 32 + 16]
379         st      %f5, [%i1 + globals + 32 + 20]
380         st      %f6, [%i1 + globals + 32 + 24]
381         st      %f7, [%i1 + globals + 32 + 28]
382         st      %f8, [%i1 + globals + 64 + 0]
383         st      %f9, [%i1 + globals + 64 + 4]
384         st      %f10, [%i1 + globals + 64 + 8]
385         st      %f11, [%i1 + globals + 64 + 12]
386         st      %f12, [%i1 + globals + 64 + 16]
387         st      %f13, [%i1 + globals + 64 + 20]
388         st      %f14, [%i1 + globals + 64 + 24]
389         st      %f15, [%i1 + globals + 64 + 28]
390         st      %f16, [%i1 + globals + 64 + 32]
391         st      %f17, [%i1 + globals + 64 + 36]
392         st      %f18, [%i1 + globals + 64 + 40]
393         st      %f19, [%i1 + globals + 64 + 44]
394         st      %f20, [%i1 + globals + 64 + 48]
395         st      %f21, [%i1 + globals + 64 + 52]
396         st      %f22, [%i1 + globals + 64 + 56]
397         st      %f23, [%i1 + globals + 64 + 60]
398         st      %f24, [%i1 + globals + 64 + 64]
399         st      %f25, [%i1 + globals + 64 + 68]
400         st      %f26, [%i1 + globals + 64 + 72]
401         st      %f27, [%i1 + globals + 64 + 76]
402         st      %f28, [%i1 + globals + 64 + 80]
403         st      %f29, [%i1 + globals + 64 + 84]
404         st      %f30, [%i1 + globals + 64 + 88]
405         st      %f31, [%i1 + globals + 64 + 92]
406 #ifdef  notdef
407         mov     %fsr,%g1
408         st      %g1, [%i1 + globals + 64 + 96]
409         mov     %fq,%g1
410         st      %g1, [%i1 + globals + 64 + 100]
411 #endif
412
413         st      %c0, [%i1 + globals + 168 + 0]                  ! Save all coprocessor registers 
414         st      %c1, [%i1 + globals + 168 + 4]
415         st      %c2, [%i1 + globals + 168 + 8]
416         st      %c3, [%i1 + globals + 168 + 12]
417         st      %c4, [%i1 + globals + 168 + 16]
418         st      %c5, [%i1 + globals + 168 + 20]
419         st      %c6, [%i1 + globals + 168 + 24]
420         st      %c7, [%i1 + globals + 168 + 28]
421         st      %c8, [%i1 + globals + 200 + 0]
422         st      %c9, [%i1 + globals + 200 + 4]
423         st      %c10, [%i1 + globals + 200 + 8]
424         st      %c11, [%i1 + globals + 200 + 12]
425         st      %c12, [%i1 + globals + 200 + 16]
426         st      %c13, [%i1 + globals + 200 + 20]
427         st      %c14, [%i1 + globals + 200 + 24]
428         st      %c15, [%i1 + globals + 200 + 28]
429         st      %c16, [%i1 + globals + 200 + 32]
430         st      %c17, [%i1 + globals + 200 + 36]
431         st      %c18, [%i1 + globals + 200 + 40]
432         st      %c19, [%i1 + globals + 200 + 44]
433         st      %c20, [%i1 + globals + 200 + 48]
434         st      %c21, [%i1 + globals + 200 + 52]
435         st      %c22, [%i1 + globals + 200 + 56]
436         st      %c23, [%i1 + globals + 200 + 60]
437         st      %c24, [%i1 + globals + 200 + 64]
438         st      %c25, [%i1 + globals + 200 + 68]
439         st      %c26, [%i1 + globals + 200 + 72]
440         st      %c27, [%i1 + globals + 200 + 76]
441         st      %c28, [%i1 + globals + 200 + 80]
442         st      %c29, [%i1 + globals + 200 + 84]
443         st      %c30, [%i1 + globals + 200 + 88]
444         st      %c31, [%i1 + globals + 200 + 92]
445 #ifdef  notdef
446         mov     %csr,%g1
447         st      %g1, [%i1 + globals + 200 + 96]
448         mov     %cq,%g1
449         st      %g1, [%i1 + globals + 200 + 100]
450 #endif
451 #endif
452         cmp     %i2, 0
453         be,a    L1                              ! if (newsp == 0) no stack switch
454         nop
455 #ifdef  notdef
456         add     %i2, STACK_ALIGN - 1, %i2
457         and     %i2, ~(STACK_ALIGN - 1), %i2
458         sub     %i2, SA(MINFRAME), %fp
459         call    %i0
460         restore
461 #else
462         ! This used to compute a new stack frame base, write it into
463         ! FP, and restore to enter the new frame. But that left a window
464         ! in which FP could be written into the backing store for this
465         ! frame, to be tripped over later by returnto. So instead we do
466         ! the restore first, then modify SP to enter the new frame. We
467         ! can still refer to our argument as %02.
468         restore
469         add     %o2, STACK_ALIGN - 1, %o2
470         and     %o2, ~(STACK_ALIGN - 1), %o2    
471         call    %o0
472         sub     %o2, SA(MINFRAME), %sp
473 #endif  
474
475 L1:     call    %i0                     ! call f()
476         nop
477
478
479 ! returnto(area1)
480 !     struct savearea *area1;
481 #ifdef  AFS_SUN5_ENV
482         .globl returnto
483 returnto:
484 #else
485         .globl _returnto
486 _returnto:
487 #endif
488         ta      ST_FLUSH_WINDOWS                ! FLush all other active windows
489         ld      [%o0+topstack],%g1              ! sp = area1->topstack
490         sub     %g1, SA(MINFRAME), %fp  ! Adjust sp to the right place
491         sub     %fp, SA(MINFRAME), %sp
492
493 #ifdef  save_allregs
494         ld      [%o0 + globals + 32 + 0],%f0            ! Restore floating-point registers 
495         ld      [%o0 + globals + 32 + 4],%f1
496         ld      [%o0 + globals + 32 + 8],%f2
497         ld      [%o0 + globals + 32 + 12],%f3
498         ld      [%o0 + globals + 32 + 16],%f4
499         ld      [%o0 + globals + 32 + 20],%f5
500         ld      [%o0 + globals + 32 + 24],%f6
501         ld      [%o0 + globals + 32 + 28],%f7
502         ld      [%o0 + globals + 64 + 0],%f8
503         ld      [%o0 + globals + 64 + 4],%f9
504         ld      [%o0 + globals + 64 + 8],%f10
505         ld      [%o0 + globals + 64 + 12],%f11
506         ld      [%o0 + globals + 64 + 16],%f12
507         ld      [%o0 + globals + 64 + 20],%f13
508         ld      [%o0 + globals + 64 + 24],%f14
509         ld      [%o0 + globals + 64 + 28],%f15
510         ld      [%o0 + globals + 64 + 32],%f16
511         ld      [%o0 + globals + 64 + 36],%f17
512         ld      [%o0 + globals + 64 + 40],%f18
513         ld      [%o0 + globals + 64 + 44],%f19
514         ld      [%o0 + globals + 64 + 48],%f20
515         ld      [%o0 + globals + 64 + 52],%f21
516         ld      [%o0 + globals + 64 + 56],%f22
517         ld      [%o0 + globals + 64 + 60],%f23
518         ld      [%o0 + globals + 64 + 64],%f24
519         ld      [%o0 + globals + 64 + 68],%f25
520         ld      [%o0 + globals + 64 + 72],%f26
521         ld      [%o0 + globals + 64 + 76],%f27
522         ld      [%o0 + globals + 64 + 80],%f28
523         ld      [%o0 + globals + 64 + 84],%f29
524         ld      [%o0 + globals + 64 + 88],%f30
525         ld      [%o0 + globals + 64 + 92],%f31
526 #ifdef  notdef
527         ld      [%o0 + globals + 64 + 96],%g1
528         mov     %g1, %fsr
529         ld      [%o0 + globals + 64 + 100],%g1
530         mov     %g1, %fq
531 #endif
532
533         ld      [%o0 + globals + 168 + 0],%c0           ! Restore floating-point registers 
534         ld      [%o0 + globals + 168 + 4],%c1
535         ld      [%o0 + globals + 168 + 8],%c2
536         ld      [%o0 + globals + 168 + 12],%c3
537         ld      [%o0 + globals + 168 + 16],%c4
538         ld      [%o0 + globals + 168 + 20],%c5
539         ld      [%o0 + globals + 168 + 24],%c6
540         ld      [%o0 + globals + 168 + 28],%c7
541         ld      [%o0 + globals + 200 + 0],%c8
542         ld      [%o0 + globals + 200 + 4],%c9
543         ld      [%o0 + globals + 200 + 8],%c10
544         ld      [%o0 + globals + 200 + 12],%c11
545         ld      [%o0 + globals + 200 + 16],%c12
546         ld      [%o0 + globals + 200 + 20],%c13
547         ld      [%o0 + globals + 200 + 24],%c14
548         ld      [%o0 + globals + 200 + 28],%c15
549         ld      [%o0 + globals + 200 + 32],%c16
550         ld      [%o0 + globals + 200 + 36],%c17
551         ld      [%o0 + globals + 200 + 40],%c18
552         ld      [%o0 + globals + 200 + 44],%c19
553         ld      [%o0 + globals + 200 + 48],%c20
554         ld      [%o0 + globals + 200 + 52],%c21
555         ld      [%o0 + globals + 200 + 56],%c22
556         ld      [%o0 + globals + 200 + 60],%c23
557         ld      [%o0 + globals + 200 + 64],%c24
558         ld      [%o0 + globals + 200 + 68],%c25
559         ld      [%o0 + globals + 200 + 72],%c26
560         ld      [%o0 + globals + 200 + 76],%c27
561         ld      [%o0 + globals + 200 + 80],%c28
562         ld      [%o0 + globals + 200 + 84],%c29
563         ld      [%o0 + globals + 200 + 88],%c30
564         ld      [%o0 + globals + 200 + 92],%c31
565 #ifdef  notdef
566         ld      [%o0 + globals + 200 + 96],%g1
567         mov     %g1, %csr
568         ld      [%o0 + globals + 200 + 100],%g1
569         mov     %g1, %cq
570 #endif
571 #endif
572         ld      [%o0 + globals + 28], %g1               ! Restore global regs back
573         mov     %g1, %y
574         ld      [%o0 + globals + 0], %g1
575         ld      [%o0 + globals + 4], %g2
576         ld      [%o0 + globals + 8], %g3
577         ld      [%o0 + globals + 12],%g4
578         ld      [%o0 + globals + 16],%g5
579         ld      [%o0 + globals + 20],%g6
580         ld      [%o0 + globals + 24],%g7
581
582         /* The following 3 lines are equivalent to: _PRE_Block = 0 */
583 #ifdef  AFS_SUN5_ENV
584         set     PRE_Block, %l0
585 #else
586         set     _PRE_Block, %l0
587 #endif
588         mov     0,%l1
589         stb     %l1, [%l0]
590
591         restore                                 
592         restore
593
594         retl
595         nop
596
597 #endif /* sparc */
598 #ifdef ibm032
599 |
600 |       Information Technology Center
601 |       Carnegie-Mellon University
602 |
603 |
604         .data
605         .globl  .oVncs
606         .set            .oVncs,0
607
608         .globl  _savecontext
609 _savecontext:
610         .long           _.savecontext
611
612         .globl  _returnto
613 _returnto:
614         .long           _.returnto
615
616 |
617 |       Process assembly language assist for Sailboats.
618 |
619
620         .text
621         .align 2
622
623 |
624 | struct savearea {
625 |       char    *topstack;
626 | }
627 |
628
629 | Offsets of fields
630 .set topstack,0
631
632 | Stuff to allow saving/restoring registers
633 .set regspace,64
634 .set freg,0
635
636 |
637 | savecontext(f, area1, newsp)
638 |    int (*f)(); struct savearea *area1; char *newsp;
639 |
640
641         .globl  _.savecontext
642 _.savecontext:
643         ai      sp,sp,-regspace         | Save frame pointer & ...
644                                         | ... allocate space for 16 registers
645 | Save registers
646         stm     r0,0(sp)                        | Change this if save fewer regs.
647 | Set preemption semaphore
648         get     r6,$1
649         get     r7,$_PRE_Block
650         putc    r6,0(r7)                        | PRE_Block = 1
651 | r3 = base of savearea
652         put     sp,topstack(r3)         | area1->topstack = sp
653 | New sp is in r4.
654         cis     r4,0
655         be      L1                      | If newsp == 0, no stack switch
656         cas     sp,r4,r0                        | Switch to new stack
657 L1:
658         get     r6,0(r2)                        | r2 = _f
659         balrx   r15,r6                  | f()
660         cas     r0,r2,r0
661
662 |
663 | returnto(area2)
664 |     struct savearea *area2;
665 |
666
667         .globl _.returnto
668 _.returnto:
669         get     sp,topstack(r2)
670 | Now in the context of the savecontext stack to be restored.
671 | Start with the registers...
672 | Clear preemption semaphore
673         get     r6,$0
674         get     r7,$_PRE_Block
675         putc    r6,0(r7)                        | PRE_Block = 0
676         lm      r0,0(sp)                | Change if saving fewer regs.
677         brx     r15             | Return to previous process
678         ai      sp,sp,regspace
679  .data
680  .ltorg
681 #endif
682
683 #ifdef AFS_AIX22_ENV
684 /*
685 #
686 #       Information Technology Center
687 #       Carnegie-Mellon University
688 #
689 */
690 /*
691 #
692 #       Process assembly language assist for Sailboats.
693 #
694 */
695
696         .text
697         .globl  .savecontext
698         .align 1
699
700 /*
701 #
702 # struct savearea {
703 #       char    *topstack;
704 # }
705 #
706 */
707
708
709 /*# Offsets of fields*/
710 .set topstack,0
711
712 /*# Stuff to allow saving/restoring registers*/
713 .set regspace,64
714 .set freg,0
715
716 /*
717 #
718 # savecontext(f, area1, newsp)
719 #    int (*f)(); struct savearea *area1; char *newsp;
720 #
721 */
722
723 .savecontext:
724         ai      1,1,-regspace           # Save frame pointer & ...
725
726 /*# Save registers*/
727         stm     0,0(1)                  # Change this if save fewer regs.
728         lr      14,0
729 /*# Set preemption semaphore*/
730         lis     6,1
731         l       7,4(14)
732         stc     6,0(7)
733 /*# r3 = base of savearea*/
734         st      1,topstack(3)           # area1->topstack = sp
735 /*# New sp is in r4.*/
736         ci      4,0
737         beq     L1                      # If newsp == 0, no stack switch
738         cas     1,4,0                   # Switch to new stack
739 L1:
740         l       6,0(2)                  # r2 = _f
741         balrx   15,6                    # f()
742         cas     0,2,0
743         .data   3
744         .globl  _savecontext
745 _savecontext:
746         .long   .savecontext
747         .long   _PRE_Block
748 /*
749 #
750 # returnto(area2)
751 #     struct savearea *area2;
752 #
753 */
754
755         .text
756         .globl  .returnto
757         .align 1
758 .returnto:
759         l       1,topstack(2)
760 /*
761 # Now in the context of the savecontext stack to be restored.
762 # Start with the registers...
763 # Clear preemption semaphore
764 */
765         lr      14,0
766         lis     6,0
767         l       7,4(14)
768         stc     6,0(7)
769         lm      0,0(1)          # Change if saving fewer regs.
770         brx     15              # Return to previous process
771         ai      1,1,regspace
772         .data   3
773         .globl  _returnto
774 _returnto:
775         .long   .returnto
776         .long   _PRE_Block
777 #endif /* AFS_AIX_ENV */
778
779 #ifdef vax
780 /*
781 #
782 #       Information Technology Center
783 #       Carnegie-Mellon University
784 #
785 #
786 */
787         .data
788
789 /*
790 #
791 #       Algorithm: "Monkey see, monkey do"
792 #
793 */
794
795         .text
796
797 /*
798 #
799 # struct savearea {
800 #       char    *topstack;
801 # }
802 #
803 */
804
805         .set    topstack,0
806
807 /* Stuff to allow saving/restoring registers */
808
809 /*
810 # savecontext(f, area1, newsp)
811 #     int (*f)(); struct savearea *area1; char *newsp;
812 */
813
814 /* Stack offsets of arguments */
815         .set    f,4
816         .set    area1,8
817         .set    newsp,12
818
819 .globl  _PRE_Block
820 .globl  _savecontext
821
822 _savecontext:
823         .word 0x0ffc    # Save regs R2-R11
824         movb    $1,_PRE_Block           # Critical section for preemption code
825         pushl   ap                      # save old ap
826         pushl   fp                      # save old fp    
827         movl    area1(ap),r0            # r0 = base of savearea
828         movl    sp,topstack(r0)         # area->topstack = sp
829         movl    newsp(ap),r0            # Get new sp
830         beql    L1                      # if new sp is 0, dont change stacks
831         movl    r0,sp                   # else switch to new stack
832 L1:
833         movl    f(ap),r1                # r1 = f
834         calls   $0,0(r1)                # f()
835
836 /* It is impossible to be here, so abort() */
837
838         calls   $0,_abort
839
840 /*
841 # returnto(area2)
842 #     struct savearea *area2;
843 */
844
845 /* Stack offset of argument */
846         .set    area2,4
847
848         .globl _returnto
849 _returnto:
850         .word   0x0                     # Who cares about these regs?
851         movl    area2(ap),r0            # r0 = address of area2
852         movl    topstack(r0),sp         # Restore sp
853         movl    (sp)+,fp                # Restore fp
854         movl    (sp)+,ap                # ,,,,
855         clrb    _PRE_Block              # End of preemption critical section
856         ret
857
858         pushl   $1234                   # The author will gloat
859         calls   $0,_abort
860 #endif
861
862 #ifdef mips
863 #ifdef  sgi
864         .option pic2
865
866 #include <regdef.h> /* Allow use of symbolic names for registers. */
867 /* 9 sregs, ra, 6 fp regs, gp, pad to 8 byte boundary */
868 #define regspace 9 * 4 + 4 + 6 * 8 + 4 + 4
869 #define floats 0
870 #define registers floats + 6 * 8
871 #define returnaddr regspace - 4
872 #define topstack 0
873 #define GPOFF   regspace - 8
874         .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
875         .ent savecontext /* Insert debugger information. */
876 savecontext:
877         .set    noreorder
878         .cpload t9                      # set up gp for KPIC
879         .set    reorder
880         subu sp, regspace
881         .cprestore GPOFF                # trigger t9/jalr
882         .set    noreorder
883         li      t0, 1
884         .extern PRE_Block
885         sb      t0, PRE_Block
886         .set    reorder
887         .frame  sp, regspace, ra
888 /* Save registers. */
889         sw      s0, registers + 0(sp)
890         sw      s1, registers + 4(sp)
891         sw      s2, registers + 8(sp)
892         sw      s3, registers + 12(sp)
893         sw      s4, registers + 16(sp)
894         sw      s5, registers + 20(sp)
895         sw      s6, registers + 24(sp)
896         sw      s7, registers + 28(sp)
897         sw      s8, registers + 32(sp)
898 /* Save return address */
899         sw      ra, returnaddr(sp)
900         .mask   0xc0ff0000, -4
901 /* Need to save floating point registers? */
902         s.d     $f20, floats + 0(sp)
903         s.d     $f22, floats + 8(sp)
904         s.d     $f24, floats + 16(sp)
905         s.d     $f26, floats + 24(sp)
906         s.d     $f28, floats + 32(sp)
907         s.d     $f30, floats + 40(sp)
908         .fmask  0x55400000, regspace
909         sw      sp, topstack(a1)
910         beq     a2, $0, samestack
911         move    sp, a2
912 samestack:
913         move    t9, a0
914         j       t9
915         .end    savecontext
916
917         .globl  returnto
918         .ent    returnto
919 returnto:
920         .set    noreorder
921         .cpload t9                      # set up gp for KPIC
922         .set    reorder
923
924         lw      sp, topstack(a0)
925         lw      s0, registers + 0(sp)
926         lw      s1, registers + 4(sp)
927         lw      s2, registers + 8(sp)
928         lw      s3, registers + 12(sp)
929         lw      s4, registers + 16(sp)
930         lw      s5, registers + 20(sp)
931         lw      s6, registers + 24(sp)
932         lw      s7, registers + 28(sp)
933         lw      s8, registers + 32(sp)
934 /* Save return address */
935         lw      ra, returnaddr(sp)
936 /* Need to save floating point registers? */
937         l.d     $f20, floats + 0(sp)
938         l.d     $f22, floats + 8(sp)
939         l.d     $f24, floats + 16(sp)
940         l.d     $f26, floats + 24(sp)
941         l.d     $f28, floats + 32(sp)
942         l.d     $f30, floats + 40(sp)
943         .set    noreorder
944         addu    sp, regspace
945         la      t0, PRE_Block
946         j       ra
947         sb      zero, 0(t0)
948         .set    reorder
949         .end    returnto
950
951 #else
952 /* Code for MIPS R2000/R3000 architecture
953  * Written by Zalman Stern April 30th, 1989.
954  */
955 #include <regdef.h> /* Allow use of symbolic names for registers. */
956 #define regspace 9 * 4 + 4 + 6 * 8
957 #define floats 0
958 #define registers floats + 6 * 8
959 #define returnaddr regspace - 4
960 #define topstack 0
961         .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
962         .ent savecontext /* Insert debugger information. */
963 savecontext:
964         li      t0, 1
965         .extern PRE_Block
966         sb      t0, PRE_Block
967         subu    sp, regspace
968         .frame  sp, regspace, ra
969 /* Save registers. */
970         sw      s0, registers + 0(sp)
971         sw      s1, registers + 4(sp)
972         sw      s2, registers + 8(sp)
973         sw      s3, registers + 12(sp)
974         sw      s4, registers + 16(sp)
975         sw      s5, registers + 20(sp)
976         sw      s6, registers + 24(sp)
977         sw      s7, registers + 28(sp)
978         sw      s8, registers + 32(sp)
979 /* Save return address */
980         sw      ra, returnaddr(sp)
981         .mask   0xc0ff0000, -4
982 /* Need to save floating point registers? */
983         s.d     $f20, floats + 0(sp)
984         s.d     $f22, floats + 8(sp)
985         s.d     $f24, floats + 16(sp)
986         s.d     $f26, floats + 24(sp)
987         s.d     $f28, floats + 32(sp)
988         s.d     $f30, floats + 40(sp)
989         .fmask  0x55400000, regspace
990         sw      sp, topstack(a1)
991         beq     a2, $0, samestack
992         addu    sp, $0, a2
993 samestack:
994         jal     a0
995         .end    savecontext
996
997         .globl  returnto
998         .ent    returnto
999 returnto:
1000         lw      sp, topstack(a0)
1001         lw      s0, registers + 0(sp)
1002         lw      s1, registers + 4(sp)
1003         lw      s2, registers + 8(sp)
1004         lw      s3, registers + 12(sp)
1005         lw      s4, registers + 16(sp)
1006         lw      s5, registers + 20(sp)
1007         lw      s6, registers + 24(sp)
1008         lw      s7, registers + 28(sp)
1009         lw      s8, registers + 32(sp)
1010 /* Save return address */
1011         lw      ra, returnaddr(sp)
1012 /* Need to save floating point registers? */
1013         l.d     $f20, floats + 0(sp)
1014         l.d     $f22, floats + 8(sp)
1015         l.d     $f24, floats + 16(sp)
1016         l.d     $f26, floats + 24(sp)
1017         l.d     $f28, floats + 32(sp)
1018         l.d     $f30, floats + 40(sp)
1019         addu    sp, regspace
1020         sb      $0, PRE_Block
1021         j       ra
1022         .end    returnto
1023 #endif  /* sgi */
1024 #endif
1025
1026 #ifdef AFS_HPUX_ENV
1027 #include "process.s.hpux"
1028 #endif /* AFS_HPUX_ENV */
1029
1030 #ifdef __alpha
1031 /* Code for DEC Alpha architecture */
1032 #ifdef  AFS_OSF_ENV
1033 #include <machine/asm.h>
1034 #include <machine/regdef.h>
1035 #define fs0     $f2
1036 #define fs1     $f3
1037 #define fs2     $f4
1038 #define fs3     $f5
1039 #define fs4     $f6
1040 #define fs5     $f7
1041 #define fs6     $f8
1042 #define fs7     $f9
1043 #elif defined(AFS_XBSD_ENV)
1044 #include <machine/asm.h>
1045 #else   /* !OSF && !XBSD */
1046 #include <mach/alpha/asm.h>
1047 #endif  /* OSF */
1048
1049 #define FRAMESIZE ((8*8)+8+(7*8))
1050 #define floats 0
1051 #define registers (floats+(8*8))
1052 #define returnaddr (FRAMESIZE-8)
1053 #define topstack 0
1054
1055 #ifdef AFS_OSF_ENV
1056 IMPORT(PRE_Block,4)
1057 #endif
1058 .align  4
1059 #ifdef  AFS_OSF_ENV
1060 NESTED(savecontext,FRAMESIZE,ra)
1061 #else   /* OSF */
1062 NESTED(savecontext,3,FRAMESIZE,ra,0x0400f700,0x000003fc)
1063 #endif  /* OSF */
1064         ldgp    gp,0(pv)
1065         lda     t0, 1(zero)
1066         stl     t0, PRE_Block
1067         lda     sp,-FRAMESIZE(sp)
1068 /* Save callee-saved registers. */
1069         stq     s0, (registers+0) (sp)
1070         stq     s1, (registers+8) (sp)
1071         stq     s2, (registers+16) (sp)
1072         stq     s3, (registers+24) (sp)
1073         stq     s4, (registers+32) (sp)
1074         stq     s5, (registers+40) (sp)
1075         stq     s6, (registers+48) (sp)
1076 /* Save return address */
1077         stq     ra, returnaddr(sp)
1078
1079         .mask   (M_S0|M_S1|M_S2|M_S3|M_S4|M_S5|M_S6|M_RA), -FRAMESIZE
1080
1081 /* Save floating point registers */
1082         stt     fs0, (floats+0) (sp)
1083         stt     fs1, (floats+8) (sp)
1084         stt     fs2, (floats+16) (sp)
1085         stt     fs3, (floats+24) (sp)
1086         stt     fs4, (floats+32) (sp)
1087         stt     fs5, (floats+40) (sp)
1088         stt     fs6, (floats+48) (sp)
1089         stt     fs7, (floats+56) (sp)
1090
1091         .prologue       1
1092         stq     sp, topstack(a1)
1093         or      a0,zero,pv              /* call point in pv */
1094         beq     a2, samestack
1095         or      a2,zero,sp              /* switch stack */
1096 samestack:
1097         jsr     ra,(pv),0               /* off we go */
1098         END(savecontext)
1099
1100 #ifdef  AFS_OSF_ENV
1101 LEAF(returnto)
1102 #else   
1103 LEAF(returnto,1)
1104 #endif  
1105         ldgp    gp,0(pv)
1106
1107         .prologue       1
1108         ldq     sp, topstack(a0)
1109 /* Restore callee-saved regs */
1110         ldq     s0, (registers+0) (sp)
1111         ldq     s1, (registers+8) (sp)
1112         ldq     s2, (registers+16) (sp)
1113         ldq     s3, (registers+24) (sp)
1114         ldq     s4, (registers+32) (sp)
1115         ldq     s5, (registers+40) (sp)
1116         ldq     s6, (registers+48) (sp)
1117 /* Return address */
1118         ldq     ra, returnaddr(sp)
1119 /* Floating point registers */
1120         ldt     fs0, (floats+0) (sp)
1121         ldt     fs1, (floats+8) (sp)
1122         ldt     fs2, (floats+16) (sp)
1123         ldt     fs3, (floats+24) (sp)
1124         ldt     fs4, (floats+32) (sp)
1125         ldt     fs5, (floats+40) (sp)
1126         ldt     fs6, (floats+48) (sp)
1127         ldt     fs7, (floats+56) (sp)
1128         lda     sp, FRAMESIZE(sp)
1129         stl     zero, PRE_Block
1130         RET
1131         END(returnto)
1132 #endif
1133
1134 #ifdef AFS_PPC_ENV
1135 /* Comments:
1136  *    1. Registers R10..R31 and CR0..CR7 are saved
1137  *    2. "struct savearea" must hold at least 3 pointers (long)
1138  *    3. This code will only work on 32 bit machines (601..604), not 620
1139  *    4. No floating point registers are saved
1140  *    5. The save stack "frame" is bigger than absolutely necessary.  The
1141  *       PowerPC [AIX] ABI needs this extra space.
1142  */
1143
1144
1145 /* Mach-O assemblers */
1146 #if !defined(NeXT) && !defined(__APPLE__)
1147 #define r0    0
1148 #define r1    1
1149 #define r2    2
1150 #define r3    3
1151 #define r4    4
1152 #define r5    5
1153 #define r6    6
1154 #define r7    7
1155 #define r8    8
1156 #define r9    9
1157 #define r10   10
1158 #define r11   11
1159 #define r12   12
1160 #define r13   13
1161 #define r14   14
1162 #define r15   15
1163 #define r16   16
1164 #define r17   17
1165 #define r18   18
1166 #define r19   19
1167 #define r20   20
1168 #define r21   21
1169 #define r22   22
1170 #define r23   23
1171 #define r24   24
1172 #define r25   25
1173 #define r26   26
1174 #define r27   27
1175 #define r28   28
1176 #define r29   29
1177 #define r30   30
1178 #define r31   31
1179 #endif /* !NeXT && !__APPLE__ */
1180
1181
1182 /*
1183  * savecontext(int (*f)(), struct savearea *save, char *newsp)
1184  */
1185
1186 #define FRAME_SIZE    (32*4)+(8*4)
1187 #define FRAME_OFFSET  (8*4)
1188 #define TOP_OF_STACK  (0*4)
1189 #define RETURN                (1*4)
1190 #define CCR           (2*4)
1191
1192 #if defined(NeXT) || defined(__APPLE__)
1193       .globl  _savecontext
1194 _savecontext:
1195       lis     r9,ha16(_PRE_Block)     /* Disable interrupt fiddling */
1196       li      r8,1
1197       stb     r8,lo16(_PRE_Block)(r9)
1198 #else
1199       .globl  savecontext
1200 savecontext:
1201       lis     r9,PRE_Block@ha         /* Disable interrupt fiddling */
1202       li      r8,1
1203       stb     r8,PRE_Block@l(r9)
1204 #endif /* NeXT || __APPLE__ */
1205       subi    r1,r1,FRAME_SIZE
1206       mfcr    r9
1207       stw     r9,CCR(r4)
1208       stw     r10,10*4+FRAME_OFFSET(r1)       /* Save registers */
1209       stw     r11,11*4+FRAME_OFFSET(r1)
1210       stw     r12,12*4+FRAME_OFFSET(r1)
1211       stw     r13,13*4+FRAME_OFFSET(r1)
1212       stw     r14,14*4+FRAME_OFFSET(r1)
1213       stw     r15,15*4+FRAME_OFFSET(r1)
1214       stw     r16,16*4+FRAME_OFFSET(r1)
1215       stw     r17,17*4+FRAME_OFFSET(r1)
1216       stw     r18,18*4+FRAME_OFFSET(r1)
1217       stw     r19,19*4+FRAME_OFFSET(r1)
1218       stw     r20,20*4+FRAME_OFFSET(r1)
1219       stw     r21,21*4+FRAME_OFFSET(r1)
1220       stw     r22,22*4+FRAME_OFFSET(r1)
1221       stw     r23,23*4+FRAME_OFFSET(r1)
1222       stw     r24,24*4+FRAME_OFFSET(r1)
1223       stw     r25,25*4+FRAME_OFFSET(r1)
1224       stw     r26,26*4+FRAME_OFFSET(r1)
1225       stw     r27,27*4+FRAME_OFFSET(r1)
1226       stw     r28,28*4+FRAME_OFFSET(r1)
1227       stw     r29,29*4+FRAME_OFFSET(r1)
1228       stw     r30,30*4+FRAME_OFFSET(r1)
1229       stw     r31,31*4+FRAME_OFFSET(r1)
1230       stw     r1,TOP_OF_STACK(r4)
1231       cmpi    0,r5,0                          /* New stack specified? */
1232       mflr    r0
1233       stw     r0,RETURN(r4)
1234       mtlr    r3
1235       beq     L1                             /* No - don't muck with pointer */
1236
1237       mr      r1,r5
1238 L1:        blr                                     /* Return */
1239
1240 /*
1241  * returnto(struct savearea *area)
1242  */
1243 #if defined(NeXT) || defined(__APPLE__)
1244       .globl  _returnto
1245 _returnto:
1246 #else
1247       .globl  returnto
1248 returnto:
1249 #endif /* NeXT || __APPLE__ */
1250       lwz     r1,TOP_OF_STACK(r3)             /* Update stack pointer */
1251       lwz     r0,RETURN(r3)                   /* Get return address */
1252       mtlr    r0
1253       lwz     r4,CCR(r3)
1254       mtcrf   0xFF,r4
1255       lwz     r10,10*4+FRAME_OFFSET(r1)       /* Restore registers */
1256       lwz     r11,11*4+FRAME_OFFSET(r1)
1257       lwz     r12,12*4+FRAME_OFFSET(r1)
1258       lwz     r13,13*4+FRAME_OFFSET(r1)
1259       lwz     r14,14*4+FRAME_OFFSET(r1)
1260       lwz     r15,15*4+FRAME_OFFSET(r1)
1261       lwz     r16,16*4+FRAME_OFFSET(r1)
1262       lwz     r17,17*4+FRAME_OFFSET(r1)
1263       lwz     r18,18*4+FRAME_OFFSET(r1)
1264       lwz     r19,19*4+FRAME_OFFSET(r1)
1265       lwz     r20,20*4+FRAME_OFFSET(r1)
1266       lwz     r21,21*4+FRAME_OFFSET(r1)
1267       lwz     r22,22*4+FRAME_OFFSET(r1)
1268       lwz     r23,23*4+FRAME_OFFSET(r1)
1269       lwz     r24,24*4+FRAME_OFFSET(r1)
1270       lwz     r25,25*4+FRAME_OFFSET(r1)
1271       lwz     r26,26*4+FRAME_OFFSET(r1)
1272       lwz     r27,27*4+FRAME_OFFSET(r1)
1273       lwz     r28,28*4+FRAME_OFFSET(r1)
1274       lwz     r29,29*4+FRAME_OFFSET(r1)
1275       lwz     r30,30*4+FRAME_OFFSET(r1)
1276       lwz     r31,31*4+FRAME_OFFSET(r1)
1277 #if defined(NeXT) || defined(__APPLE__)
1278       lis     r9,ha16(_PRE_Block)         /* Re-enable interrupt fiddling */
1279       li      r8,0
1280       stb     r8,lo16(_PRE_Block)(r9)
1281 #else
1282       lis     r9,PRE_Block@ha         /* Re-enable interrupt fiddling */
1283       li      r8,0
1284       stb     r8,PRE_Block@l(r9)
1285 #endif /* NeXT || __APPLE__ */
1286       addi    r1,r1,FRAME_SIZE
1287       blr
1288 #endif
1289         
1290 #if defined(__linux__) && defined(__ELF__)
1291         .section .note.GNU-stack,"",%progbits
1292 #endif