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