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