Stylistic tweak lwp/process.o machinery
[openafs.git] / src / lwp / process.default.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 #ifndef AFS_ARM_DARWIN_ENV
15         /* register definitions */
16        fp      .req    r11
17        ip      .req    r12
18        sp      .req    r13
19        lp      .req    r14
20        pc      .req    r15
21 #endif
22
23        /*
24           savecontext(f, area1, newsp)
25                int (*f)()#if defined(RIOS);
26                struct savearea *area1;
27                char *newsp;
28        */
29
30        /* Arguments appear as:     f in r0, area1 in r1, newsp in r2 */
31
32        .text
33        .align  0
34 #ifndef AFS_ARM_DARWIN_ENV
35        .globl  savecontext
36        .type   savecontext, #function
37 savecontext:
38 #else
39        .globl  _savecontext
40 _savecontext:
41 #endif
42         @ build the frame
43         mov     ip, sp
44         stmfd   sp!, {fp, ip, lr, pc}
45         sub     fp, ip, #4
46         @ stack r0 - r10, current fp
47         stmfd   sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, fp}
48         str     sp, [r1, #0]
49         @ check if newsp is zero
50         movs    r2, r2
51         movne   sp, r2
52         @ call function ...
53 #ifdef AFS_ARM_DARWIN_ENV
54         bx      r0
55 #else
56         mov     pc, r0
57 #endif
58
59        /*
60          returnto(area2)
61             struct savearea *area2;
62        */
63
64        /* area2 is in r0. */
65
66 #ifndef AFS_ARM_DARWIN_ENV
67        .globl returnto
68        .type  returnto, #function
69 returnto:
70 #else
71        .globl _returnto
72 _returnto:
73 #endif
74        @ restore r0-r10, fp
75        ldr     r0, [r0, #0]
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}
79
80 #endif /* __arm32__ or __arm__ */
81
82 #if defined(RIOS)
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
88  */
89
90
91 /*
92  * savecontext(f, area1, newsp)
93  *     int (*f)(); struct savearea *area1; char *newsp;
94  */
95         .set    topstack, 0
96         .set    cr0, 0
97         .set    toc, 2
98         .set    r0, 0
99         .set    r1, 1
100         .set    r2, 2
101         .set    r3, 3
102         .set    r4, 4
103         .set    r5, 5
104         .set    r6, 6
105         .set    r7, 7
106         .set    r12, 12
107         .set    a_f, r3
108         .set    a_area1, r4
109         .set    a_newsp, r5
110
111         .set    argarea,  32
112         .set    linkarea, 24
113         .set    nfprs,    18
114         .set    ngprs,    20
115         .set    szdsa,    8*nfprs+4*ngprs+linkarea+argarea
116
117         .csect .savecontext[PR]
118         .globl .savecontext[PR]
119
120         mflr    r0                      # save link register
121                 
122 /*
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.
126  */
127         stfd  14, -144(1)
128         stfd  15, -136(1)
129
130         mfcr    r12                     # save CR
131
132         stfd  16, -128(1)
133         stfd  17, -120(1)
134
135         l       11, 0(a_f)              # r11 <- *(a_f)
136
137         stfd  18, -112(1)
138         stfd  19, -104(1)
139
140         cmpi    cr0, a_newsp, 0         # cr0 <- (a_newsp :: 0)
141
142         stfd  20, -96(1)
143         stfd  21, -88(1)
144         stfd  22, -80(1)
145
146         mtlr    11                      # set up lr early so prefetch works
147
148         stfd  23, -72(1)
149         stfd  24, -64(1)
150         stfd  25, -56(1)
151
152         st      r0, 8(r1)               # save return addr
153
154         stfd  26, -48(1)
155         stfd  27, -40(1)
156         stfd  28, -32(1)
157
158         st      12, 4(r1)               # save CR
159
160         stfd  29, -24(1)
161         stfd  30, -16(1)
162         stfd  31, -8(1)
163
164 /*
165  *  save general-purpose registers
166  */
167         stm     12, -8*nfprs-4*ngprs(r1)# save the general-purpose regs
168         stu     r1, -szdsa(r1)          # dec SP and save back chain
169
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
173
174         st      r1, topstack(a_area1)   # save old SP
175         
176         beq    L1                       # if (a_newsp == 0) goto L1
177
178         mr      r1, r5                  # r1 <- a_newsp -- load new SP
179
180 L1:     brl                             # pc <- lr      -- (*a_f)()
181
182 /*
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.
187  */
188         .set    a_area2, r3
189
190         .csect  .returnto[PR]
191         .globl  .returnto[PR]
192
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
196
197         l       8, 8(1)                 # restore lr
198         mtlr    8                       # do it early so prefetch works
199
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
204
205 /*
206  * restore FPRs here!
207  */
208         lfd  14, -144(1)
209         lfd  15, -136(1)
210         lfd  16, -128(1)
211         lfd  17, -120(1)
212         lfd  18, -112(1)
213         lfd  19, -104(1)
214         lfd  20, -96(1)
215         lfd  21, -88(1)
216         lfd  22, -80(1)
217         lfd  23, -72(1)
218         lfd  24, -64(1)
219         lfd  25, -56(1)
220         lfd  26, -48(1)
221         lfd  27, -40(1)
222         lfd  28, -32(1)
223         lfd  29, -24(1)
224         lfd  30, -16(1)
225         lfd  31, -8(1)
226
227         brl                             # pc <- lr      -- return
228
229         .toc
230
231 PRE_Block.S:
232         .tc     PRE_Block[tc], PRE_Block[ua]
233         .extern PRE_Block[ua]
234
235 #endif  /* RIOS */
236         
237 #ifdef mc68000
238 /*
239 #
240 #       Information Technology Center
241 #       Carnegie-Mellon University
242 #
243 #
244 */
245         .data
246
247 /*
248 #
249 #       Process assembly language assist for Suns.
250 #
251 */
252
253         .text
254         .even
255
256 /*
257 #
258 # struct savearea {
259 #       char    *topstack;
260 # }
261 #
262 */
263
264         .globl  _PRE_Block
265
266 topstack =      0
267
268 /* Stuff to allow saving/restoring registers */
269 nregs   =       13
270 regs    =       0x3ffe                  | d1-d7 & a0-a5
271
272 /*
273 # savecontext(f, area1, newsp)
274 #     int (*f)(); struct savearea *area1; char *newsp;
275 */
276
277 /* Stack offsets of arguments */
278 f       =       8
279 area1   =       12
280 newsp   =       16
281
282         .globl  _savecontext
283 _savecontext:
284         movb    #1,_PRE_Block           | Dont allow any interrupt finagling
285         link    a6,#-(nregs*4)          | Save frame pointer & ...
286                                         | ... allocate space for nregs registers
287 /* Save registers */
288         moveml  #regs,sp@
289
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
295 forw1:
296         movl    a6@(f),a0               | a0 = f
297         jbsr    a0@                     | f()
298
299 /* It is impossible to be here, so abort() */
300
301         jbsr    _abort
302
303 /*
304 # returnto(area2)
305 #     struct savearea *area2;
306 */
307
308 /* Stack offset of argument */
309 area2   =       8
310
311         .globl _returnto
312 _returnto:
313         link    a6,#0
314         movl    a6@(area2),a0           | Base of savearea
315         movl    a0@(topstack),sp        | Restore sp
316 /* Restore registers */
317         moveml  sp@,#regs
318
319         addl    #(nregs*4),sp
320         movl    sp,a6                   | Argghh...be careful here
321         unlk    a6
322         clrb    _PRE_Block
323         rts                             | Return to previous process
324 #endif /* mc68000 */
325 #ifdef  sparc
326 #ifdef  AFS_SUN5_ENV
327 #define _ASM    1
328 #include        <sys/asm_linkage.h>
329 #include  <sys/trap.h>
330 #else
331 #ifdef AFS_XBSD_ENV
332 #include <machine/trap.h>
333 #define ST_FLUSH_WINDOWS ST_FLUSHWIN
334 #define MINFRAME 92
335 #define SA(x) (((x)+7)&~7)
336 #define STACK_ALIGN 8
337 #else /* SunOS 4: */
338 #include        <sun4/asm_linkage.h>
339 #include  <sun4/trap.h>
340 #endif
341 #endif
342         .data   
343 #ifdef  AFS_SUN5_ENV
344         .globl  PRE_Block
345 #else
346         .globl  _PRE_Block
347 #endif
348 topstack        = 0
349 globals = 4
350 /*
351 # savecontext(f, area1, newsp)
352 #     int (*f)(); struct savearea *area1; char *newsp;
353 */
354         .text
355 #ifdef  AFS_SUN5_ENV
356         .globl  savecontext
357 savecontext:
358 #else
359         .globl  _savecontext
360 _savecontext:
361 #endif
362         save    %sp, -SA(MINFRAME), %sp ! Get new window
363         ta      ST_FLUSH_WINDOWS                ! FLush all other active windows
364
365         /* The following 3 lines do the equivalent of: _PRE_Block = 1 */
366 #ifdef  AFS_SUN5_ENV
367         set     PRE_Block, %l0
368 #else
369         set     _PRE_Block, %l0
370 #endif
371         mov     1,%l1
372         stb     %l1, [%l0]
373
374         st      %fp,[%i1+topstack]              ! area1->topstack = sp
375         
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]
383         mov     %y, %g1
384         st      %g1, [%i1 + globals + 28]
385
386 #ifdef  save_allregs
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]
419 #ifdef  notdef
420         mov     %fsr,%g1
421         st      %g1, [%i1 + globals + 64 + 96]
422         mov     %fq,%g1
423         st      %g1, [%i1 + globals + 64 + 100]
424 #endif
425
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]
458 #ifdef  notdef
459         mov     %csr,%g1
460         st      %g1, [%i1 + globals + 200 + 96]
461         mov     %cq,%g1
462         st      %g1, [%i1 + globals + 200 + 100]
463 #endif
464 #endif
465         cmp     %i2, 0
466         be,a    L1                              ! if (newsp == 0) no stack switch
467         nop
468 #ifdef  notdef
469         add     %i2, STACK_ALIGN - 1, %i2
470         and     %i2, ~(STACK_ALIGN - 1), %i2
471         sub     %i2, SA(MINFRAME), %fp
472         call    %i0
473         restore
474 #else
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.
481         restore
482         add     %o2, STACK_ALIGN - 1, %o2
483         and     %o2, ~(STACK_ALIGN - 1), %o2    
484         call    %o0
485         sub     %o2, SA(MINFRAME), %sp
486 #endif  
487
488 L1:     call    %i0                     ! call f()
489         nop
490
491
492 ! returnto(area1)
493 !     struct savearea *area1;
494 #ifdef  AFS_SUN5_ENV
495         .globl returnto
496 returnto:
497 #else
498         .globl _returnto
499 _returnto:
500 #endif
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
505
506 #ifdef  save_allregs
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
539 #ifdef  notdef
540         ld      [%o0 + globals + 64 + 96],%g1
541         mov     %g1, %fsr
542         ld      [%o0 + globals + 64 + 100],%g1
543         mov     %g1, %fq
544 #endif
545
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
578 #ifdef  notdef
579         ld      [%o0 + globals + 200 + 96],%g1
580         mov     %g1, %csr
581         ld      [%o0 + globals + 200 + 100],%g1
582         mov     %g1, %cq
583 #endif
584 #endif
585         ld      [%o0 + globals + 28], %g1               ! Restore global regs back
586         mov     %g1, %y
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
594
595         /* The following 3 lines are equivalent to: _PRE_Block = 0 */
596 #ifdef  AFS_SUN5_ENV
597         set     PRE_Block, %l0
598 #else
599         set     _PRE_Block, %l0
600 #endif
601         mov     0,%l1
602         stb     %l1, [%l0]
603
604         restore                                 
605         restore
606
607         retl
608         nop
609
610 #endif /* sparc */
611 #ifdef ibm032
612 |
613 |       Information Technology Center
614 |       Carnegie-Mellon University
615 |
616 |
617         .data
618         .globl  .oVncs
619         .set            .oVncs,0
620
621         .globl  _savecontext
622 _savecontext:
623         .long           _.savecontext
624
625         .globl  _returnto
626 _returnto:
627         .long           _.returnto
628
629 |
630 |       Process assembly language assist for Sailboats.
631 |
632
633         .text
634         .align 2
635
636 |
637 | struct savearea {
638 |       char    *topstack;
639 | }
640 |
641
642 | Offsets of fields
643 .set topstack,0
644
645 | Stuff to allow saving/restoring registers
646 .set regspace,64
647 .set freg,0
648
649 |
650 | savecontext(f, area1, newsp)
651 |    int (*f)(); struct savearea *area1; char *newsp;
652 |
653
654         .globl  _.savecontext
655 _.savecontext:
656         ai      sp,sp,-regspace         | Save frame pointer & ...
657                                         | ... allocate space for 16 registers
658 | Save registers
659         stm     r0,0(sp)                        | Change this if save fewer regs.
660 | Set preemption semaphore
661         get     r6,$1
662         get     r7,$_PRE_Block
663         putc    r6,0(r7)                        | PRE_Block = 1
664 | r3 = base of savearea
665         put     sp,topstack(r3)         | area1->topstack = sp
666 | New sp is in r4.
667         cis     r4,0
668         be      L1                      | If newsp == 0, no stack switch
669         cas     sp,r4,r0                        | Switch to new stack
670 L1:
671         get     r6,0(r2)                        | r2 = _f
672         balrx   r15,r6                  | f()
673         cas     r0,r2,r0
674
675 |
676 | returnto(area2)
677 |     struct savearea *area2;
678 |
679
680         .globl _.returnto
681 _.returnto:
682         get     sp,topstack(r2)
683 | Now in the context of the savecontext stack to be restored.
684 | Start with the registers...
685 | Clear preemption semaphore
686         get     r6,$0
687         get     r7,$_PRE_Block
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
691         ai      sp,sp,regspace
692  .data
693  .ltorg
694 #endif
695
696 #ifdef AFS_AIX22_ENV
697 /*
698 #
699 #       Information Technology Center
700 #       Carnegie-Mellon University
701 #
702 */
703 /*
704 #
705 #       Process assembly language assist for Sailboats.
706 #
707 */
708
709         .text
710         .globl  .savecontext
711         .align 1
712
713 /*
714 #
715 # struct savearea {
716 #       char    *topstack;
717 # }
718 #
719 */
720
721
722 /*# Offsets of fields*/
723 .set topstack,0
724
725 /*# Stuff to allow saving/restoring registers*/
726 .set regspace,64
727 .set freg,0
728
729 /*
730 #
731 # savecontext(f, area1, newsp)
732 #    int (*f)(); struct savearea *area1; char *newsp;
733 #
734 */
735
736 .savecontext:
737         ai      1,1,-regspace           # Save frame pointer & ...
738
739 /*# Save registers*/
740         stm     0,0(1)                  # Change this if save fewer regs.
741         lr      14,0
742 /*# Set preemption semaphore*/
743         lis     6,1
744         l       7,4(14)
745         stc     6,0(7)
746 /*# r3 = base of savearea*/
747         st      1,topstack(3)           # area1->topstack = sp
748 /*# New sp is in r4.*/
749         ci      4,0
750         beq     L1                      # If newsp == 0, no stack switch
751         cas     1,4,0                   # Switch to new stack
752 L1:
753         l       6,0(2)                  # r2 = _f
754         balrx   15,6                    # f()
755         cas     0,2,0
756         .data   3
757         .globl  _savecontext
758 _savecontext:
759         .long   .savecontext
760         .long   _PRE_Block
761 /*
762 #
763 # returnto(area2)
764 #     struct savearea *area2;
765 #
766 */
767
768         .text
769         .globl  .returnto
770         .align 1
771 .returnto:
772         l       1,topstack(2)
773 /*
774 # Now in the context of the savecontext stack to be restored.
775 # Start with the registers...
776 # Clear preemption semaphore
777 */
778         lr      14,0
779         lis     6,0
780         l       7,4(14)
781         stc     6,0(7)
782         lm      0,0(1)          # Change if saving fewer regs.
783         brx     15              # Return to previous process
784         ai      1,1,regspace
785         .data   3
786         .globl  _returnto
787 _returnto:
788         .long   .returnto
789         .long   _PRE_Block
790 #endif /* AFS_AIX_ENV */
791
792 #ifdef vax
793 /*
794 #
795 #       Information Technology Center
796 #       Carnegie-Mellon University
797 #
798 #
799 */
800         .data
801
802 /*
803 #
804 #       Algorithm: "Monkey see, monkey do"
805 #
806 */
807
808         .text
809
810 /*
811 #
812 # struct savearea {
813 #       char    *topstack;
814 # }
815 #
816 */
817
818         .set    topstack,0
819
820 /* Stuff to allow saving/restoring registers */
821
822 /*
823 # savecontext(f, area1, newsp)
824 #     int (*f)(); struct savearea *area1; char *newsp;
825 */
826
827 /* Stack offsets of arguments */
828         .set    f,4
829         .set    area1,8
830         .set    newsp,12
831
832 .globl  _PRE_Block
833 .globl  _savecontext
834
835 _savecontext:
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
845 L1:
846         movl    f(ap),r1                # r1 = f
847         calls   $0,0(r1)                # f()
848
849 /* It is impossible to be here, so abort() */
850
851         calls   $0,_abort
852
853 /*
854 # returnto(area2)
855 #     struct savearea *area2;
856 */
857
858 /* Stack offset of argument */
859         .set    area2,4
860
861         .globl _returnto
862 _returnto:
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
867         movl    (sp)+,ap                # ,,,,
868         clrb    _PRE_Block              # End of preemption critical section
869         ret
870
871         pushl   $1234                   # The author will gloat
872         calls   $0,_abort
873 #endif
874
875 #ifdef mips
876 #ifdef  sgi
877         .option pic2
878
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
882 #define floats 0
883 #define registers floats + 6 * 8
884 #define returnaddr regspace - 4
885 #define topstack 0
886 #define GPOFF   regspace - 8
887         .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
888         .ent savecontext /* Insert debugger information. */
889 savecontext:
890         .set    noreorder
891         .cpload t9                      # set up gp for KPIC
892         .set    reorder
893         subu sp, regspace
894         .cprestore GPOFF                # trigger t9/jalr
895         .set    noreorder
896         li      t0, 1
897         .extern PRE_Block
898         sb      t0, PRE_Block
899         .set    reorder
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)
913         .mask   0xc0ff0000, -4
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
922         sw      sp, topstack(a1)
923         beq     a2, $0, samestack
924         move    sp, a2
925 samestack:
926         move    t9, a0
927         j       t9
928         .end    savecontext
929
930         .globl  returnto
931         .ent    returnto
932 returnto:
933         .set    noreorder
934         .cpload t9                      # set up gp for KPIC
935         .set    reorder
936
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         .set    noreorder
957         addu    sp, regspace
958         la      t0, PRE_Block
959         j       ra
960         sb      zero, 0(t0)
961         .set    reorder
962         .end    returnto
963
964 #else
965 /* Code for MIPS R2000/R3000 architecture
966  * Written by Zalman Stern April 30th, 1989.
967  */
968 #include <regdef.h> /* Allow use of symbolic names for registers. */
969 #define regspace 9 * 4 + 4 + 6 * 8
970 #define floats 0
971 #define registers floats + 6 * 8
972 #define returnaddr regspace - 4
973 #define topstack 0
974         .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
975         .ent savecontext /* Insert debugger information. */
976 savecontext:
977         li      t0, 1
978         .extern PRE_Block
979         sb      t0, PRE_Block
980         subu    sp, regspace
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)
994         .mask   0xc0ff0000, -4
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
1003         sw      sp, topstack(a1)
1004         beq     a2, $0, samestack
1005         addu    sp, $0, a2
1006 samestack:
1007         jal     a0
1008         .end    savecontext
1009
1010         .globl  returnto
1011         .ent    returnto
1012 returnto:
1013         lw      sp, topstack(a0)
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)
1032         addu    sp, regspace
1033         sb      $0, PRE_Block
1034         j       ra
1035         .end    returnto
1036 #endif  /* sgi */
1037 #endif
1038
1039 #ifdef AFS_HPUX_ENV
1040 #include "process.s.hpux"
1041 #endif /* AFS_HPUX_ENV */
1042
1043 #ifdef __alpha
1044 /* Code for DEC Alpha architecture */
1045 #ifdef  AFS_OSF_ENV
1046 #include <machine/asm.h>
1047 #include <machine/regdef.h>
1048 #define fs0     $f2
1049 #define fs1     $f3
1050 #define fs2     $f4
1051 #define fs3     $f5
1052 #define fs4     $f6
1053 #define fs5     $f7
1054 #define fs6     $f8
1055 #define fs7     $f9
1056 #elif defined(AFS_XBSD_ENV)
1057 #include <machine/asm.h>
1058 #else   /* !OSF && !XBSD */
1059 #include <mach/alpha/asm.h>
1060 #endif  /* OSF */
1061
1062 #define FRAMESIZE ((8*8)+8+(7*8))
1063 #define floats 0
1064 #define registers (floats+(8*8))
1065 #define returnaddr (FRAMESIZE-8)
1066 #define topstack 0
1067
1068 #ifdef AFS_OSF_ENV
1069 IMPORT(PRE_Block,4)
1070 #endif
1071 .align  4
1072 #ifdef  AFS_OSF_ENV
1073 NESTED(savecontext,FRAMESIZE,ra)
1074 #else   /* OSF */
1075 NESTED(savecontext,3,FRAMESIZE,ra,0x0400f700,0x000003fc)
1076 #endif  /* OSF */
1077         ldgp    gp,0(pv)
1078         lda     t0, 1(zero)
1079         stl     t0, PRE_Block
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)
1091
1092         .mask   (M_S0|M_S1|M_S2|M_S3|M_S4|M_S5|M_S6|M_RA), -FRAMESIZE
1093
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)
1103
1104         .prologue       1
1105         stq     sp, topstack(a1)
1106         or      a0,zero,pv              /* call point in pv */
1107         beq     a2, samestack
1108         or      a2,zero,sp              /* switch stack */
1109 samestack:
1110         jsr     ra,(pv),0               /* off we go */
1111         END(savecontext)
1112
1113 #ifdef  AFS_OSF_ENV
1114 LEAF(returnto)
1115 #else   
1116 LEAF(returnto,1)
1117 #endif  
1118         ldgp    gp,0(pv)
1119
1120         .prologue       1
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)
1142         stl     zero, PRE_Block
1143         RET
1144         END(returnto)
1145 #endif
1146
1147 #ifdef AFS_PPC_ENV
1148 /* Comments:
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.
1155  */
1156
1157
1158 /* Mach-O assemblers */
1159 #if !defined(NeXT) && !defined(__APPLE__)
1160 #define r0    0
1161 #define r1    1
1162 #define r2    2
1163 #define r3    3
1164 #define r4    4
1165 #define r5    5
1166 #define r6    6
1167 #define r7    7
1168 #define r8    8
1169 #define r9    9
1170 #define r10   10
1171 #define r11   11
1172 #define r12   12
1173 #define r13   13
1174 #define r14   14
1175 #define r15   15
1176 #define r16   16
1177 #define r17   17
1178 #define r18   18
1179 #define r19   19
1180 #define r20   20
1181 #define r21   21
1182 #define r22   22
1183 #define r23   23
1184 #define r24   24
1185 #define r25   25
1186 #define r26   26
1187 #define r27   27
1188 #define r28   28
1189 #define r29   29
1190 #define r30   30
1191 #define r31   31
1192 #endif /* !NeXT && !__APPLE__ */
1193
1194
1195 /*
1196  * savecontext(int (*f)(), struct savearea *save, char *newsp)
1197  */
1198
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)
1203 #define CCR           (2*4)
1204
1205 #if defined(NeXT) || defined(__APPLE__)
1206       .globl  _savecontext
1207 _savecontext:
1208       lis     r9,ha16(_PRE_Block)     /* Disable interrupt fiddling */
1209       li      r8,1
1210       stb     r8,lo16(_PRE_Block)(r9)
1211 #else
1212       .globl  savecontext
1213 savecontext:
1214       lis     r9,PRE_Block@ha         /* Disable interrupt fiddling */
1215       li      r8,1
1216       stb     r8,PRE_Block@l(r9)
1217 #endif /* NeXT || __APPLE__ */
1218       subi    r1,r1,FRAME_SIZE
1219       mfcr    r9
1220       stw     r9,CCR(r4)
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? */
1245       mflr    r0
1246       stw     r0,RETURN(r4)
1247       mtlr    r3
1248       beq     L1                             /* No - don't muck with pointer */
1249
1250       mr      r1,r5
1251 L1:        blr                                     /* Return */
1252
1253 /*
1254  * returnto(struct savearea *area)
1255  */
1256 #if defined(NeXT) || defined(__APPLE__)
1257       .globl  _returnto
1258 _returnto:
1259 #else
1260       .globl  returnto
1261 returnto:
1262 #endif /* NeXT || __APPLE__ */
1263       lwz     r1,TOP_OF_STACK(r3)             /* Update stack pointer */
1264       lwz     r0,RETURN(r3)                   /* Get return address */
1265       mtlr    r0
1266       lwz     r4,CCR(r3)
1267       mtcrf   0xFF,r4
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 */
1292       li      r8,0
1293       stb     r8,lo16(_PRE_Block)(r9)
1294 #else
1295       lis     r9,PRE_Block@ha         /* Re-enable interrupt fiddling */
1296       li      r8,0
1297       stb     r8,PRE_Block@l(r9)
1298 #endif /* NeXT || __APPLE__ */
1299       addi    r1,r1,FRAME_SIZE
1300       blr
1301 #endif
1302         
1303 #if defined(__linux__) && defined(__ELF__)
1304         .section .note.GNU-stack,"",%progbits
1305 #endif