* asm_wrapper_patcher: Fixed two typos for powerpc-linux.
[cacao.git] / src / vm / jit / powerpc / asmpart.S
1 /* src/vm/jit/powerpc/asmpart.S - Java-C interface functions for PowerPC
2                 
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software.text;  you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation;  either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY ;  without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program;  if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Andreas Krall
28             Reinhard Grafl
29             Stefan Ring
30
31    Changes: Christian Thalinger
32
33    $Id: asmpart.S 3727 2005-11-21 22:01:57Z twisti $
34
35 */
36
37
38 #include "config.h"
39
40 #include "md-abi.h"
41 #include "md-asm.h"
42
43 #include "vm/jit/methodheader.h"
44 #include "vm/jit/powerpc/offsets.h"
45
46
47         .text
48
49         .align 2
50
51         .globl asm_calljavafunction
52         .globl asm_calljavafunction_int
53
54         .globl asm_calljavafunction2
55         .globl asm_calljavafunction2int
56         .globl asm_calljavafunction2long
57         .globl asm_calljavafunction2float
58         .globl asm_calljavafunction2double
59
60         .globl asm_call_jit_compiler
61
62         .globl asm_handle_nat_exception
63         .globl asm_handle_exception
64
65         .globl asm_wrapper_patcher
66
67         .globl asm_cacheflush
68         .globl asm_initialize_thread_stack
69         .globl asm_perform_threadswitch
70         .globl asm_switchstackandcall
71         .globl asm_criticalsections
72         .globl asm_getclassvalues_atomic
73
74
75 /********************* function asm_calljavafunction ***************************
76 *                                                                              *
77 *   This function calls a Java-method (which possibly needs compilation)       *
78 *   with up to 4 address parameters.                                           *
79 *                                                                              *
80 *   This functions calls the JIT-compiler which eventually translates the      *
81 *   method into machine code.                                                  *
82 *                                                                              *
83 *   C-prototype:                                                               *
84 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
85 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
86 *                                                                              *
87 *******************************************************************************/
88                 
89         .align 2
90
91         .long   0                         /* catch type all                       */
92         .long   calljava_xhandler         /* handler pc                           */
93         .long   calljava_xhandler         /* end pc                               */
94         .long   asm_calljavafunction      /* start pc                             */
95         .long   1                         /* extable size                         */
96         .long   0                         /* line number table start              */
97         .long   0                         /* line number table size               */
98         .long   0                         /* fltsave                              */
99         .long   0                         /* intsave                              */
100         .long   0                         /* isleaf                               */
101         .long   0                         /* IsSync                               */
102         .long   24                        /* frame size                           */
103         .long   0                         /* method pointer (pointer to name)     */
104
105 asm_calljavafunction:
106 asm_calljavafunction_int:
107         mflr    r0
108         stw     r0,LA_LR_OFFSET(r1)
109         stwu    r1,-40*4(r1)
110
111 #if defined(__DARWIN__)
112         stw     itmp1,10*4(sp)            /* register r11 is callee saved         */
113 #endif
114         stw     pv,11*4(sp)               /* save PV register                     */
115
116         stw     itmp3,12*4(sp)            /* registers r14-r31 are callee saved   */
117         stfd    ftmp1,14*4(sp)            /* registers f14-f31 are callee saved   */
118         stfd    ftmp2,16*4(sp)
119
120 #if defined(__DARWIN__)
121         stw     t1,18*4(r1)
122         stw     t2,19*4(r1)
123         stw     t3,20*4(r1)
124         stw     t4,21*4(r1)
125         stw     t5,22*4(r1)
126         stw     t6,23*4(r1)
127         stw     t7,24*4(r1)
128
129         stfd    ft0,26*4(r1)
130         stfd    ft1,28*4(r1)
131         stfd    ft2,30*4(r1)
132         stfd    ft3,32*4(r1)
133         stfd    ft4,34*4(r1)
134         stfd    ft5,36*4(r1)
135 #else
136         SAVE_TEMPORARY_REGISTERS(18)      /* the offset has to be even            */
137 #endif
138
139         stw     a0,36(r1)
140         addi    itmp1,r1,36
141         mr      a0,a1
142         mr      a1,a2
143         mr      a2,a3
144         mr      a3,a4
145
146 #if defined(__DARWIN__)
147         lis     mptr,ha16(asm_call_jit_compiler)
148         addi    mptr,mptr,lo16(asm_call_jit_compiler)
149 #else
150         lis     mptr,asm_call_jit_compiler@ha
151         addi    mptr,mptr,asm_call_jit_compiler@l
152 #endif
153         stw     mptr,32(r1)
154         addi    mptr,r1,28
155
156         lwz     pv,4(mptr)
157         mtctr   pv
158         bctrl
159
160 1:
161         mflr    itmp1
162 #if defined(__DARWIN__)
163         addi    pv,itmp1,lo16(asm_calljavafunction-1b)
164 #else
165         addi    pv,itmp1,(asm_calljavafunction-1b)@l
166 #endif
167
168 L_asm_calljavafunction_restore:
169 #if defined(__DARWIN__)
170         lwz     itmp1,10*4(sp)            /* register r11 is callee saved         */
171 #endif
172         lwz     pv,11*4(sp)               /* save PV register                     */
173
174         lwz     itmp3,12*4(sp)
175         lfd     ftmp1,14*4(sp)            /* registers f14-f31 are callee saved   */
176         lfd     ftmp2,16*4(sp)
177
178 #if defined(__DARWIN__)
179         lwz     t1,18*4(r1)
180         lwz     t2,19*4(r1)
181         lwz     t3,20*4(r1)
182         lwz     t4,21*4(r1)
183         lwz     t5,22*4(r1)
184         lwz     t6,23*4(r1)
185         lwz     t7,24*4(r1)
186
187         lfd     ft0,26*4(r1)
188         lfd     ft1,28*4(r1)
189         lfd     ft2,30*4(r1)
190         lfd     ft3,32*4(r1)
191         lfd     ft4,34*4(r1)
192         lfd     ft5,36*4(r1)
193 #else
194         RESTORE_TEMPORARY_REGISTERS(18)   /* the offset has to be even            */
195 #endif
196
197         lwz     r0,40*4+LA_LR_OFFSET(r1)
198         mtlr    r0
199         addi    r1,r1,40*4
200         blr
201
202 calljava_xhandler:
203         mr      a0,itmp1
204         bl      builtin_throw_exception
205         li      v0,0                      /* return NULL                          */
206         b       L_asm_calljavafunction_restore
207
208
209
210
211         .align 2
212
213         .long   0                         /* catch type all                       */
214         .long   calljava_xhandler2        /* handler pc                           */
215         .long   calljava_xhandler2        /* end pc                               */
216         .long   asm_calljavafunction2     /* start pc                             */
217         .long   1                         /* extable size                         */
218         .long   0                         /* line number table start              */
219         .long   0                         /* line number table size               */
220         .long   0                         /* fltsave                              */
221         .long   0                         /* intsave                              */
222         .long   0                         /* isleaf                               */
223         .long   0                         /* IsSync                               */
224         .long   24                        /* frame size                           */
225         .long   0                         /* method pointer (pointer to name)     */
226
227 asm_calljavafunction2:
228 asm_calljavafunction2int:
229 asm_calljavafunction2long:
230 asm_calljavafunction2float:
231 asm_calljavafunction2double:
232         mflr    r0
233         stw     r0,LA_LR_OFFSET(r1)
234         stwu    r1,-40*4(r1)
235
236 #if defined(__DARWIN__)
237         stw     itmp1,10*4(sp)            /* register r11 is callee saved         */
238 #endif
239         stw     pv,11*4(sp)               /* save PV register                     */
240
241         stw     itmp3,12*4(sp)            /* registers r14-r31 are callee saved   */
242         stfd    ftmp1,14*4(sp)            /* registers f14-f31 are callee saved   */
243         stfd    ftmp2,16*4(sp)
244
245 #if defined(__DARWIN__)
246         stw     t1,18*4(r1)
247         stw     t2,19*4(r1)
248         stw     t3,20*4(r1)
249         stw     t4,21*4(r1)
250         stw     t5,22*4(r1)
251         stw     t6,23*4(r1)
252         stw     t7,24*4(r1)
253
254         stfd    ft0,26*4(r1)
255         stfd    ft1,28*4(r1)
256         stfd    ft2,30*4(r1)
257         stfd    ft3,32*4(r1)
258         stfd    ft4,34*4(r1)
259         stfd    ft5,36*4(r1)
260 #else
261         SAVE_TEMPORARY_REGISTERS(18)      /* the offset has to be even            */
262 #endif
263
264         stw     r3,36(r1)                 /* save method pointer for compiler     */
265         mr      itmp1,r6                  /* pointer to arg block                 */
266         mr      itmp2,r4                  /* arg count                            */
267
268         addi    itmp1,itmp1,-sizejniblock /* initialize pointer (smaller code)    */
269         addi    itmp2,itmp2,1             /* initialize argument count            */
270         li      r17,0                     /* initialize integer argument counter  */
271         li      r18,0                     /* initialize float argument counter    */
272
273 L_register_copy:
274         addi    itmp1,itmp1,sizejniblock  /* goto next argument block             */
275         addi    itmp2,itmp2,-1            /* argument count - 1                   */
276         mr.     itmp2,itmp2
277         beq     L_register_copy_done
278
279         lwz     itmp3,offjniitemtype+4(itmp1)
280         andi.   r0,itmp3,0x0002           /* is this a float/double type?         */
281         bne     L_register_handle_float
282
283         cmpwi   r17,INT_ARG_CNT           /* are we out of integer argument       */
284         beq     L_register_copy           /* registers? yes, next loop            */
285
286         andi.   r0,itmp3,0x0001           /* is this a long type?                 */
287         bne     L_register_handle_long
288
289 L_register_handle_int:
290 #if defined(__DARWIN__)
291         lis     itmp3,ha16(jumptable_int)
292         addi    itmp3,itmp3,lo16(jumptable_int)
293 #else
294         lis     itmp3,jumptable_int@ha
295         addi    itmp3,itmp3,jumptable_int@l
296 #endif
297         slwi    r19,r17,2                 /* multiple of 4-bytes                  */
298         add     itmp3,itmp3,r19           /* calculate address of jumptable       */
299         lwz     itmp3,0(itmp3)            /* load function address                */
300         addi    r17,r17,1                 /* integer argument counter + 1         */
301         mtctr   itmp3
302         bctr
303
304 L_register_handle_long:
305 #if defined(__DARWIN__)
306         lis     itmp3,ha16(jumptable_long)
307         addi    itmp3,itmp3,lo16(jumptable_long)
308 #else
309         lis     itmp3,jumptable_long@ha
310         addi    itmp3,itmp3,jumptable_long@l
311 #endif
312         addi    r19,r17,1                 /* align to even numbers                */
313         srwi    r19,r19,1
314         slwi    r19,r19,1
315         slwi    r19,r19,2                 /* multiple of 4-bytes                  */
316         add     itmp3,itmp3,r19           /* calculate address of jumptable       */
317         lwz     itmp3,0(itmp3)            /* load function address                */
318         addi    r17,r17,1                 /* integer argument counter + 1         */
319         mtctr   itmp3
320         bctr
321
322 L_register_handle_float:
323 L_register_copy_done:
324
325 L_stack_copy_done:
326         addi    itmp1,r1,36
327 #if defined(__DARWIN__)
328         lis     mptr,ha16(asm_call_jit_compiler)
329         addi    mptr,mptr,lo16(asm_call_jit_compiler)
330 #else
331         lis     mptr,asm_call_jit_compiler@ha
332         addi    mptr,mptr,asm_call_jit_compiler@l
333 #endif
334         stw     mptr,32(r1)
335         addi    mptr,r1,28
336
337         lwz     pv,4(mptr)
338         mtctr   pv
339         bctrl
340 1:
341         mflr    itmp1
342 #if defined(__DARWIN__)
343         addi    pv,itmp1,lo16(asm_calljavafunction2-1b)
344 #else
345         addi    pv,itmp1,(asm_calljavafunction2-1b)@l
346 #endif
347
348 L_asm_calljavafunction2_restore:
349 #if defined(__DARWIN__)
350         lwz     itmp1,10*4(sp)            /* register r11 is callee saved         */
351 #endif
352         lwz     pv,11*4(sp)               /* save PV register                     */
353
354         lwz     itmp3,12*4(sp)
355         lfd     ftmp1,14*4(sp)            /* registers f14-f31 are callee saved   */
356         lfd     ftmp2,16*4(sp)
357
358 #if defined(__DARWIN__)
359         lwz     t1,18*4(r1)
360         lwz     t2,19*4(r1)
361         lwz     t3,20*4(r1)
362         lwz     t4,21*4(r1)
363         lwz     t5,22*4(r1)
364         lwz     t6,23*4(r1)
365         lwz     t7,24*4(r1)
366
367         lfd     ft0,26*4(r1)
368         lfd     ft1,28*4(r1)
369         lfd     ft2,30*4(r1)
370         lfd     ft3,32*4(r1)
371         lfd     ft4,34*4(r1)
372         lfd     ft5,36*4(r1)
373 #else
374         RESTORE_TEMPORARY_REGISTERS(18)   /* the offset has to be even            */
375 #endif
376
377         lwz     r0,40*4+LA_LR_OFFSET(r1)
378         mtlr    r0
379         addi    r1,r1,40*4
380         blr
381
382 calljava_xhandler2:
383         mr      r3,itmp1
384         bl      builtin_throw_exception
385         li      v0,0                      /* return NULL                          */
386         b       L_asm_calljavafunction2_restore
387
388
389 jumptable_int:
390         .long   L_handle_a0
391         .long   L_handle_a1
392         .long   L_handle_a2
393         .long   L_handle_a3
394         .long   L_handle_a4
395         .long   L_handle_a5
396         .long   L_handle_a6
397         .long   L_handle_a7
398
399 L_handle_a0:
400         lwz     a0,offjniitem+4(itmp1)
401         b       L_register_copy
402 L_handle_a1:
403         lwz     a1,offjniitem+4(itmp1)
404         b       L_register_copy
405 L_handle_a2:
406         lwz     a2,offjniitem+4(itmp1)
407         b       L_register_copy
408 L_handle_a3:
409         lwz     a3,offjniitem+4(itmp1)
410         b       L_register_copy
411 L_handle_a4:
412         lwz     a4,offjniitem+4(itmp1)
413         b       L_register_copy
414 L_handle_a5:
415         lwz     a5,offjniitem+4(itmp1)
416         b       L_register_copy
417 L_handle_a6:
418         lwz     a6,offjniitem+4(itmp1)
419         b       L_register_copy
420 L_handle_a7:
421         lwz     a7,offjniitem+4(itmp1)
422         b       L_register_copy
423
424
425 jumptable_long:
426 #if defined(__DARWIN__)
427 #else
428         /* we have two entries here, so we get the even argument register
429         alignment for linux */
430
431         .long   L_handle_a0_a1
432         .long   0
433         .long   L_handle_a2_a3
434         .long   0
435         .long   L_handle_a4_a5
436         .long   0
437         .long   L_handle_a6_a7
438         .long   0
439 #endif
440
441 L_handle_a0_a1:
442         lwz     a0,offjniitem+0(itmp1)
443         lwz     a1,offjniitem+4(itmp1)
444         b       L_register_copy
445 L_handle_a2_a3:
446         lwz     a2,offjniitem+0(itmp1)
447         lwz     a3,offjniitem+4(itmp1)
448         b       L_register_copy
449 L_handle_a4_a5:
450         lwz     a4,offjniitem+0(itmp1)
451         lwz     a5,offjniitem+4(itmp1)
452         b       L_register_copy
453 L_handle_a6_a7:
454         lwz     a6,offjniitem+0(itmp1)
455         lwz     a7,offjniitem+4(itmp1)
456         b       L_register_copy
457
458
459 /* asm_call_jit_compiler *******************************************************
460
461    Invokes the compiler for untranslated JavaVM methods.
462
463 *******************************************************************************/
464
465 asm_call_jit_compiler:
466         mflr    r0
467         stw     r0,LA_LR_OFFSET(r1)         /* save return address                */
468         stwu    r1,-((LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo)(r1)
469         stw     itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 1*4)(r1)
470
471         mr      itmp1,r0                    /* save return address to other reg.  */
472         lwz     itmp3,-12(itmp1)
473         srwi    itmp3,itmp3,16
474         andi.   itmp3,itmp3,31
475         cmpwi   itmp3,mptrn
476         beq     noregchange
477         lwz     itmp3,4(itmp1)
478         extsh   itmp3,itmp3
479         add     mptr,itmp3,itmp1
480         lwz     itmp3,8(itmp1)
481         srwi    itmp3,itmp3,16
482         cmpwi   itmp3,0x3dad
483         bne     noregchange
484         lwz     itmp3,8(itmp1)
485         slwi    itmp3,itmp3,16
486         add     mptr,mptr,itmp3
487                 
488 noregchange:
489         stw     mptr,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 2*4)(r1)
490
491 #if defined(__DARWIN__)
492         stw     a0,(LA_WORD_SIZE+5+0)*4(r1)
493         stw     a1,(LA_WORD_SIZE+5+1)*4(r1)
494         stw     a2,(LA_WORD_SIZE+5+2)*4(r1)
495         stw     a3,(LA_WORD_SIZE+5+3)*4(r1)
496         stw     a4,(LA_WORD_SIZE+5+4)*4(r1)
497         stw     a5,(LA_WORD_SIZE+5+5)*4(r1)
498         stw     a6,(LA_WORD_SIZE+5+6)*4(r1)
499         stw     a7,(LA_WORD_SIZE+5+7)*4(r1)
500
501         stfd    fa0,(LA_WORD_SIZE+5+8)*4(r1)
502         stfd    fa1,(LA_WORD_SIZE+5+10)*4(r1)
503         stfd    fa2,(LA_WORD_SIZE+5+12)*4(r1)
504         stfd    fa3,(LA_WORD_SIZE+5+14)*4(r1)
505         stfd    fa4,(LA_WORD_SIZE+5+16)*4(r1)
506         stfd    fa5,(LA_WORD_SIZE+5+18)*4(r1)
507         stfd    fa6,(LA_WORD_SIZE+5+20)*4(r1)
508         stfd    fa7,(LA_WORD_SIZE+5+22)*4(r1)
509         stfd    fa8,(LA_WORD_SIZE+5+24)*4(r1)
510         stfd    fa9,(LA_WORD_SIZE+5+26)*4(r1)
511         stfd    fa10,(LA_WORD_SIZE+5+28)*4(r1)
512         stfd    fa11,(LA_WORD_SIZE+5+30)*4(r1)
513         stfd    fa12,(LA_WORD_SIZE+5+32)*4(r1)
514 #else
515         SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1)
516 #endif
517
518         addi    a0,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)
519         li      a1,0                        /* we don't have pv handy             */
520         addi    a2,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo
521         lwz     a3,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo+LA_LR_OFFSET(sp)
522         mr      a4,a3                       /* xpc is equal to ra                 */
523         bl      stacktrace_create_extern_stackframeinfo
524
525         lwz     itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 1*4)(r1)
526         lwz     a0,0(itmp1)
527         bl      jit_compile                 /* compile the Java method            */
528         mr      pv,r3                       /* move address to pv register        */
529
530         addi    a0,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)
531         bl      stacktrace_remove_stackframeinfo
532
533 #if defined(__DARWIN__)
534         lwz     a0,(LA_WORD_SIZE+5+0)*4(r1)
535         lwz     a1,(LA_WORD_SIZE+5+1)*4(r1)
536         lwz     a2,(LA_WORD_SIZE+5+2)*4(r1)
537         lwz     a3,(LA_WORD_SIZE+5+3)*4(r1)
538         lwz     a4,(LA_WORD_SIZE+5+4)*4(r1)
539         lwz     a5,(LA_WORD_SIZE+5+5)*4(r1)
540         lwz     a6,(LA_WORD_SIZE+5+6)*4(r1)
541         lwz     a7,(LA_WORD_SIZE+5+7)*4(r1)
542
543         lfd     fa0,(LA_WORD_SIZE+5+8)*4(r1)
544         lfd     fa1,(LA_WORD_SIZE+5+10)*4(r1)
545         lfd     fa2,(LA_WORD_SIZE+5+12)*4(r1)
546         lfd     fa3,(LA_WORD_SIZE+5+14)*4(r1)
547         lfd     fa4,(LA_WORD_SIZE+5+16)*4(r1)
548         lfd     fa5,(LA_WORD_SIZE+5+18)*4(r1)
549         lfd     fa6,(LA_WORD_SIZE+5+20)*4(r1)
550         lfd     fa7,(LA_WORD_SIZE+5+22)*4(r1)
551         lfd     fa8,(LA_WORD_SIZE+5+24)*4(r1)
552         lfd     fa9,(LA_WORD_SIZE+5+26)*4(r1)
553         lfd     fa10,(LA_WORD_SIZE+5+28)*4(r1)
554         lfd     fa11,(LA_WORD_SIZE+5+30)*4(r1)
555         lfd     fa12,(LA_WORD_SIZE+5+32)*4(r1)
556 #else
557         RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1)
558 #endif
559
560         lwz     mptr,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 2*4)(r1)
561
562         lwz     itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo+LA_LR_OFFSET(r1)
563         mtlr    itmp1
564         addi    r1,r1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo
565
566         mr.     pv,pv                       /* test for exception                 */
567         beq     L_asm_call_jit_compiler_exception
568
569         lwz     itmp3,-12(itmp1)
570         extsh   itmp3,itmp3
571         add     mptr,mptr,itmp3
572         stw     pv,0(mptr)                  /* store method address               */
573
574         mtctr   pv                          /* move method address to control reg */
575         bctr                                /* and call the Java method           */
576
577 L_asm_call_jit_compiler_exception:
578 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
579         mflr    r0
580         stw     r0,LA_LR_OFFSET(sp)
581         stwu    sp,-LA_SIZE_ALIGNED(sp)     /* preserve linkage area              */
582         bl      builtin_asm_get_exceptionptrptr
583         lwz     r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
584         mtlr    r0      
585         addi    sp,sp,LA_SIZE_ALIGNED
586 #else
587 # if defined(__DARWIN__)
588         lwz     v0,lo16(_no_threads_exceptionptr-0b)(pv)
589 # else
590         lis     v0,_no_threads_exceptionptr@ha
591         addi    v0,v0,_no_threads_exceptionptr@l
592 # endif
593 #endif
594         lwz     xptr,0(v0)                  /* get the exception pointer          */
595         li      itmp3,0
596         stw     itmp3,0(v0)                 /* clear the exception pointer        */
597
598         mflr    xpc
599         addi    xpc,xpc,-4
600         b       asm_handle_nat_exception
601
602
603 /********************* function asm_handle_exception ***************************
604 *                                                                              *
605 *   This function handles an exception. It does not use the usual calling      *
606 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
607 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
608 *   the local exception table for a handler. If no one is found, it unwinds    *
609 *   stacks and continues searching the callers.                                *
610 *                                                                              *
611 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
612 *                                                                              *
613 *******************************************************************************/
614                 
615 asm_handle_nat_exception:
616         mflr    r9
617         lwz     itmp3,4(r9)
618         extsh   itmp3,itmp3
619         add     pv,itmp3,r9
620         lwz     itmp3,8(r9)
621         srwi    itmp3,itmp3,16
622         cmpwi   itmp3,0x3dad
623         bne     asm_handle_exception
624         lwz     itmp3,8(r9)
625         slwi    itmp3,itmp3,16
626         add     pv,pv,itmp3
627
628 asm_handle_exception:
629         addi    r1,r1,-18*4
630         stw     r0,0*4(r1)
631         stw     r2,1*4(r1)
632         stw     r3,2*4(r1)
633         stw     r4,3*4(r1)
634         stw     r5,4*4(r1)
635         stw     r6,5*4(r1)
636         stw     r7,6*4(r1)
637         stw     r8,7*4(r1)
638         stw     r9,8*4(r1)
639         stw     r10,9*4(r1)
640         stw     r16,10*4(r1)
641         stw     r17,11*4(r1)
642         stw     r18,12*4(r1)
643         stw     r19,13*4(r1)
644         stw     r20,14*4(r1)
645         stw     r21,15*4(r1)
646         stw     r22,16*4(r1)
647         stw     r23,17*4(r1)
648
649         li      r9,1
650 ex_stack_loop:
651         addi    r1,r1,-4*4            /* allocate stack                           */
652         stw     xptr,0*4(r1)          /* save used register                       */
653         stw     xpc,1*4(r1)
654         mflr    xptr
655         stw     xptr,2*4(r1)
656         stw     r9,3*4(r1)
657
658         lwz     r3,0*4(r1)            /* exception pointer                        */
659         lwz     r4,MethodPointer(pv)  /* method pointer                           */
660         mr      r5,xpc                /* exception pc                             */
661 /*      mr      r6,r9 */
662         li      r6,0                  /* line number                              */
663         li      r7,4                  /* set no unwind flag                       */
664
665         /* XXX no valid stack frame chaining here */
666         addi    r1,r1,-(24+5*4)       /* 24 linkage area + 5 argument * 4         */
667         bl      builtin_trace_exception
668         addi    r1,r1,(24+5*4)
669
670         lwz     xptr,2*4(r1)
671         mtlr    xptr
672         lwz     xptr,0*4(r1)          /* restore xptr                             */
673         lwz     xpc,1*4(r1)
674         lwz     r9,3*4(r1)
675         addi    r1,r1,4*4
676
677         lwz     r3,ExTableSize(pv)    /* r3 = exception table size                */
678         mr.     r3,r3                 /* if empty table skip                      */
679         beq     empty_table
680
681         addi    r4,pv,ExTableStart    /* r4 = start of exception table            */
682
683 ex_table_loop:
684         lwz     r5,ExStartPC(r4)      /* r5 = exception start pc                  */
685         cmplw   r5,xpc                /* (startpc <= xpc)                         */
686         bgt     ex_table_cont
687         lwz     r5,ExEndPC(r4)        /* r5 = exception end pc                    */
688         cmplw   xpc,r5                /* (xpc < endpc)                            */
689         bge     ex_table_cont
690         lwz     r7,ExCatchType(r4)    /* r7 = exception catch type                */
691         mr.     r7,r7
692         beq     ex_handle_it
693
694         lwz     itmp3,offclassloaded(r7)
695         mr.     itmp3,itmp3
696         bne     L_class_loaded
697
698         /* XXX no valid stack frame chaining here */
699         addi    r1,r1,-16*4           /* allocate stack                           */
700         stw     r3,7*4(r1)            /* save used registers                      */
701         stw     r4,8*4(r1)            /* 6*4 (linkage) + 1*4 (arg1) + 7*4 (save)  */
702         stw     r9,9*4(r1)
703         stw     xptr,10*4(r1)
704         stw     xpc,11*4(r1)
705         mflr    xptr
706         stw     xptr,12*4(r1)
707         stw     r7,13*4(r1)
708
709         mr      r3,r7                 /* arg1 = exceptionclass                    */
710         bl      load_class_bootstrap
711
712         lwz     r3,7*4(r1)
713         lwz     r4,8*4(r1)
714         lwz     r9,9*4(r1)
715         lwz     xptr,10*4(r1)
716         lwz     xpc,11*4(r1)
717         lwz     itmp3,12*4(r1)
718         mtlr    itmp3
719         lwz     r7,13*4(r1)     
720         addi    r1,r1,16*4
721
722 L_class_loaded:
723         lwz     itmp3,offclasslinked(r7)
724         mr.     itmp3,itmp3
725         /* XXX no valid stack frame chaining here */
726         addi    r1,r1,-16*4           /* allocate stack                           */
727         stw     r7,13*4(r1)
728         bne     L_class_linked
729
730         stw     r3,7*4(r1)            /* save used registers                      */
731         stw     r4,8*4(r1)            /* 6*4 (linkage) + 1*4 (arg1) + 7*4 (save)  */
732         stw     r9,9*4(r1)
733         stw     xptr,10*4(r1)
734         stw     xpc,11*4(r1)
735         mflr    xptr
736         stw     xptr,12*4(r1)
737
738         mr      r3,r7                 /* arg1 = exceptionclass                    */
739         bl      link_class
740
741         lwz     r3,7*4(r1)
742         lwz     r4,8*4(r1)
743         lwz     r9,9*4(r1)
744         lwz     xptr,10*4(r1)
745         lwz     xpc,11*4(r1)
746         lwz     itmp3,12*4(r1)
747         mtlr    itmp3
748
749 L_class_linked:
750 _crit_restart1:
751         lwz     r7,13*4(r1)
752 _crit_begin1:
753         lwz     r6,offobjvftbl(xptr)  /* r6 = vftblptr(xptr)                      */
754         lwz     r7,offclassvftbl(r7)  /* r7 = vftblptr(catchtype) class (not obj) */
755         lwz     r6,offbaseval(r6)     /* r6 = baseval(xptr)                       */
756         lwz     r8,offbaseval(r7)     /* r8 = baseval(catchtype)                  */
757         lwz     r7,offdiffval(r7)     /* r7 = diffval(catchtype)                  */
758 _crit_end1:
759         subf    r6,r8,r6              /* r6 = baseval(xptr) - baseval(catchtype)  */
760         cmplw   r6,r7                 /* xptr is instanceof catchtype             */
761         addi    r1,r1,16*4
762         bgt     ex_table_cont         /* if (false) continue                      */
763
764 ex_handle_it:
765         lwz     xpc,ExHandlerPC(r4)   /* xpc = exception handler pc               */
766         mr.     r9,r9
767         beq     ex_jump
768
769         lwz     r0,0*4(r1)
770         lwz     r2,1*4(r1)
771         lwz     r3,2*4(r1)
772         lwz     r4,3*4(r1)
773         lwz     r5,4*4(r1)
774         lwz     r6,5*4(r1)
775         lwz     r7,6*4(r1)
776         lwz     r8,7*4(r1)
777         lwz     r9,8*4(r1)
778         lwz     r10,9*4(r1)
779         lwz     r16,10*4(r1)
780         lwz     r17,11*4(r1)
781         lwz     r18,12*4(r1)
782         lwz     r19,13*4(r1)
783         lwz     r20,14*4(r1)
784         lwz     r21,15*4(r1)
785         lwz     r22,16*4(r1)
786         lwz     r23,17*4(r1)
787         addi    r1,r1,18*4
788
789 ex_jump:
790         mtctr   xpc
791         bctr
792
793 ex_table_cont:
794         addi    r4,r4,ExEntrySize     /* next exception table entry               */
795         addic.  r3,r3,-1              /* decrement entry counter                  */
796         bgt     ex_table_loop         /* if (t0 > 0) next entry                   */
797
798 empty_table:
799         mr.     r9,r9                 /* if here the first time, then             */
800         beq     ex_already_cleared
801         addi    r1,r1,18*4            /* deallocate stack and                     */
802         li      r9,0                  /* clear the no unwind flag                 */
803 ex_already_cleared:
804         lwz     r3,IsSync(pv)         /* t0 = SyncOffset                          */
805         mr.     r3,r3
806         beq     no_monitor_exit       /* if zero no monitorexit                   */
807
808 #if defined(USE_THREADS)
809         add     r3,r1,r3
810         lwz     r6,-4(r3)
811
812         addi    r1,r1,-6*4
813         stw     r3,0*4(r1)
814         stw     r4,1*4(r1)
815         stw     r9,2*4(r1)
816         stw     xptr,3*4(r1)
817         stw     xpc,4*4(r1)
818         mflr    xptr
819         stw     xptr,5*4(r1)
820
821         mr      r3,r6
822         /* XXX no valid stack frame chaining here */
823         addi    r1,r1,-40
824         bl      builtin_monitorexit
825         addi    r1,r1,40
826
827         lwz     xptr,5*4(r1)
828         mtlr    xptr
829         lwz     r3,0*4(r1)
830         lwz     r4,1*4(r1)
831         lwz     r9,2*4(r1)
832         lwz     xptr,3*4(r1)
833         lwz     xpc,4*4(r1)
834         addi    r1,r1,6*4
835 #endif
836
837 no_monitor_exit:
838         lwz     r3,FrameSize(pv)      /* r3 = frame size                          */
839         add     r1,r1,r3              /* unwind stack                             */
840         mr      r3,r1                 /* r3 = pointer to save area                */
841         lwz     r4,IsLeaf(pv)         /* r4 = is leaf procedure                   */
842         mr.     r4,r4
843         bne     ex_no_restore         /* if (leaf) skip                           */
844         lwz     r4,LA_LR_OFFSET(r3)   /* restore ra                               */
845         mtlr    r4                    /* t0--                                     */
846 ex_no_restore:
847         mflr    r4                    /* the new xpc is ra                        */
848         mr      xpc,r4
849         lwz     r4,IntSave(pv)        /* r4 = saved int register count            */
850         bl      ex_int1
851 ex_int1:
852         mflr    r5
853 #if defined(__DARWIN__)
854         addi    r5,r5,lo16(ex_int2-ex_int1)
855 #else
856         addi    r5,r5,(ex_int2-ex_int1)@l
857 #endif
858         slwi    r4,r4,2
859         subf    r5,r4,r5
860         mtctr   r5
861         bctr
862         lwz     s0,-40(r3)
863         lwz     s1,-36(r3)
864         lwz     s2,-32(r3)
865         lwz     s3,-28(r3)
866         lwz     s4,-24(r3)
867         lwz     s5,-20(r3)
868         lwz     s6,-16(r3)
869         lwz     s7,-12(r3)
870         lwz     s8,-8(r3)
871         lwz     s9,-4(r3)
872
873 ex_int2:
874         subf    r3,r4,r3
875
876         lwz     r4,FltSave(pv)
877         bl      ex_flt1
878 ex_flt1:
879         mflr    r5
880 #if defined(__DARWIN__)
881         addi    r5,r5,lo16(ex_flt2-ex_flt1)
882 #else
883         addi    r5,r5,(ex_flt2-ex_flt1)@l
884 #endif
885         slwi    r4,r4,2
886         subf    r5,r4,r5
887         mtctr   r5
888         bctr
889         lfd     fs0,-80(r3)
890         lfd     fs1,-72(r3)
891         lfd     fs2,-64(r3)
892         lfd     fs3,-56(r3)
893         lfd     fs4,-48(r3)
894         lfd     fs5,-40(r3)
895         lfd     fs6,-32(r3)
896         lfd     fs7,-24(r3)
897         lfd     fs8,-16(r3)
898         lfd     fs9,-8(r3)
899
900 ex_flt2:
901         mtlr    xpc
902         lwz     itmp3,4(xpc)
903         extsh   itmp3,itmp3
904         add     pv,itmp3,xpc
905         lwz     itmp3,8(xpc)
906         srwi    itmp3,itmp3,16
907         cmpwi   itmp3,0x3dad
908         bne     ex_stack_loop
909         lwz     itmp3,8(xpc)
910         slwi    itmp3,itmp3,16
911         add     pv,pv,itmp3
912         b       ex_stack_loop
913
914
915 /* asm_wrapper_patcher *********************************************************
916
917    XXX
918
919    Stack layout:
920      20   return address into JIT code (patch position)
921      16   pointer to virtual java_objectheader
922      12   machine code (which is patched back later)
923       8   unresolved class/method/field reference
924       4   data segment displacement from load instructions
925       0   patcher function pointer to call (pv is saved here afterwards)
926
927 *******************************************************************************/
928
929 asm_wrapper_patcher:
930         mflr    r0                    /* get Java return address (leaf)           */
931         stw     r0,6*4(sp)            /* store it in the stub stackframe          */
932                                       /* keep stack 16-bytes aligned: 6+1+37 = 44 */
933         stwu    sp,-(LA_SIZE+(5+58)*4+sizestackframeinfo)(sp)
934
935 #if defined(__DARWIN__)
936         stw     a0,LA_SIZE+(5+0)*4(r1)      /* save argument registers            */
937         stw     a1,LA_SIZE+(5+1)*4(r1)      /* preserve linkage area (24 bytes)   */
938         stw     a2,LA_SIZE+(5+2)*4(r1)      /* and 4 bytes for 4 argument         */
939         stw     a3,LA_SIZE+(5+3)*4(r1)
940         stw     a4,LA_SIZE+(5+4)*4(r1)
941         stw     a5,LA_SIZE+(5+5)*4(r1)
942         stw     a6,LA_SIZE+(5+6)*4(r1)
943         stw     a7,LA_SIZE+(5+7)*4(r1)
944
945         stfd    fa0,LA_SIZE+(5+8)*4(sp)
946         stfd    fa1,LA_SIZE+(5+10)*4(sp)
947         stfd    fa2,LA_SIZE+(5+12)*4(sp)
948         stfd    fa3,LA_SIZE+(5+14)*4(sp)
949         stfd    fa4,LA_SIZE+(5+16)*4(sp)
950         stfd    fa5,LA_SIZE+(5+18)*4(sp)
951         stfd    fa6,LA_SIZE+(5+20)*4(sp)
952         stfd    fa7,LA_SIZE+(5+22)*4(sp)
953         stfd    fa8,LA_SIZE+(5+24)*4(sp)
954         stfd    fa9,LA_SIZE+(5+26)*4(sp)
955         stfd    fa10,LA_SIZE+(5+28)*4(sp)
956         stfd    fa11,LA_SIZE+(5+30)*4(sp)
957         stfd    fa12,LA_SIZE+(5+32)*4(sp)
958
959         stw     t0,(LA_WORD_SIZE+5+33)*4(r1)
960         stw     t1,(LA_WORD_SIZE+5+34)*4(r1)
961         stw     t2,(LA_WORD_SIZE+5+35)*4(r1)
962         stw     t3,(LA_WORD_SIZE+5+36)*4(r1)
963         stw     t4,(LA_WORD_SIZE+5+37)*4(r1)
964         stw     t5,(LA_WORD_SIZE+5+38)*4(r1)
965         stw     t6,(LA_WORD_SIZE+5+39)*4(r1)
966         stw     t7,(LA_WORD_SIZE+5+40)*4(r1)
967
968         stfd    ft0,(LA_WORD_SIZE+5+42)*4(r1)
969         stfd    ft1,(LA_WORD_SIZE+5+44)*4(r1)
970         stfd    ft2,(LA_WORD_SIZE+5+46)*4(r1)
971         stfd    ft3,(LA_WORD_SIZE+5+48)*4(r1)
972         stfd    ft4,(LA_WORD_SIZE+5+50)*4(r1)
973         stfd    ft5,(LA_WORD_SIZE+5+52)*4(r1)
974 #else
975         SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* save 8 int/8 float arguments   */
976         SAVE_TEMPORARY_REGISTERS(LA_WORD_SIZE+1+24)
977 #endif
978
979         stw     itmp1,LA_SIZE+(5+54)*4(sp)
980         stw     itmp2,LA_SIZE+(5+55)*4(sp)
981         stw     pv,LA_SIZE+(5+56)*4(sp)
982
983         addi    a0,sp,LA_SIZE+(5+58)*4      /* create stackframe info             */
984         mr      a1,pv
985         addi    a2,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
986         mr      a3,r0                       /* this is correct for leafs          */
987         lwz     a4,((5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo)(sp) /* pass xpc   */
988         bl      stacktrace_create_extern_stackframeinfo
989
990         addi    a0,sp,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo  /* pass sp      */
991         lwz     pv,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp) /* get function */
992         lwz     itmp1,LA_SIZE+(5+56)*4(sp)  /* move pv to position of fp          */
993         stw     itmp1,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
994         mtctr   pv                          /* call the patcher function          */
995         bctrl
996         stw     v0,LA_SIZE+(5+57)*4(sp)     /* save return value                  */
997
998         addi    a0,sp,LA_SIZE+(5+58)*4
999         bl      stacktrace_remove_stackframeinfo /* remove stackframe info        */
1000
1001 #if defined(__DARWIN__)
1002         lwz     a0,LA_SIZE+(5+0)*4(r1)
1003         lwz     a1,LA_SIZE+(5+1)*4(r1)
1004         lwz     a2,LA_SIZE+(5+2)*4(r1)
1005         lwz     a3,LA_SIZE+(5+3)*4(r1)
1006         lwz     a4,LA_SIZE+(5+4)*4(r1)
1007         lwz     a5,LA_SIZE+(5+5)*4(r1)
1008         lwz     a6,LA_SIZE+(5+6)*4(r1)
1009         lwz     a7,LA_SIZE+(5+7)*4(r1)
1010
1011         lfd     fa0,LA_SIZE+(5+8)*4(sp)
1012         lfd     fa1,LA_SIZE+(5+10)*4(sp)
1013         lfd     fa2,LA_SIZE+(5+12)*4(sp)
1014         lfd     fa3,LA_SIZE+(5+14)*4(sp)
1015         lfd     fa4,LA_SIZE+(5+16)*4(sp)
1016         lfd     fa5,LA_SIZE+(5+18)*4(sp)
1017         lfd     fa6,LA_SIZE+(5+20)*4(sp)
1018         lfd     fa7,LA_SIZE+(5+22)*4(sp)
1019         lfd     fa8,LA_SIZE+(5+24)*4(sp)
1020         lfd     fa9,LA_SIZE+(5+26)*4(sp)
1021         lfd     fa10,LA_SIZE+(5+28)*4(sp)
1022         lfd     fa11,LA_SIZE+(5+30)*4(sp)
1023         lfd     fa12,LA_SIZE+(5+32)*4(sp)
1024
1025         lwz     t0,(LA_WORD_SIZE+5+33)*4(r1)
1026         lwz     t1,(LA_WORD_SIZE+5+34)*4(r1)
1027         lwz     t2,(LA_WORD_SIZE+5+35)*4(r1)
1028         lwz     t3,(LA_WORD_SIZE+5+36)*4(r1)
1029         lwz     t4,(LA_WORD_SIZE+5+37)*4(r1)
1030         lwz     t5,(LA_WORD_SIZE+5+38)*4(r1)
1031         lwz     t6,(LA_WORD_SIZE+5+39)*4(r1)
1032         lwz     t7,(LA_WORD_SIZE+5+40)*4(r1)
1033
1034         lfd     ft0,(LA_WORD_SIZE+5+42)*4(r1)
1035         lfd     ft1,(LA_WORD_SIZE+5+44)*4(r1)
1036         lfd     ft2,(LA_WORD_SIZE+5+46)*4(r1)
1037         lfd     ft3,(LA_WORD_SIZE+5+48)*4(r1)
1038         lfd     ft4,(LA_WORD_SIZE+5+50)*4(r1)
1039         lfd     ft5,(LA_WORD_SIZE+5+52)*4(r1)
1040 #else
1041         RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* restore 8 int/8 float args  */
1042         RESTORE_TEMPORARY_REGISTERS(LA_WORD_SIZE+1+24)
1043 #endif
1044
1045         lwz     itmp1,LA_SIZE+(5+54)*4(sp)
1046         lwz     itmp2,LA_SIZE+(5+55)*4(sp)
1047         lwz     pv,LA_SIZE+(5+56)*4(sp)
1048         lwz     itmp3,LA_SIZE+(5+57)*4(sp)  /* restore return value into temp reg.*/
1049
1050         lwz     r0,(6+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp) /* restore RA   */
1051         mtlr    r0
1052
1053         mr.     itmp3,itmp3           /* check for an exception                   */
1054         beq     L_asm_wrapper_patcher_exception
1055
1056                                       /* get return address (into JIT code)       */
1057         lwz     itmp3,(5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
1058
1059                                       /* remove stack frame + patcher stub stack  */
1060         addi    sp,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
1061
1062         mtctr   itmp3
1063         bctr                          /* jump to new patched code                 */
1064
1065 L_asm_wrapper_patcher_exception:
1066         lwz     xpc,(5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
1067         addi    sp,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
1068
1069 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1070         mflr    r0
1071         stw     r0,LA_LR_OFFSET(sp)
1072         stwu    sp,-(LA_SIZE+1*4)(sp) /* preserve linkage area                    */
1073         stw     xpc,LA_SIZE+0*4(sp)
1074         bl      builtin_asm_get_exceptionptrptr
1075         lwz     xpc,LA_SIZE+0*4(sp)
1076         lwz     r0,LA_SIZE+1*4+LA_LR_OFFSET(sp)
1077         mtlr    r0
1078         addi    sp,sp,LA_SIZE+1*4
1079 #else
1080 # if defined(__DARWIN__)
1081         lwz     v0,lo16(_no_threads_exceptionptr-0b)(pv)
1082 # else
1083         lis     v0,_no_threads_exceptionptr@ha
1084         addi    v0,v0,_no_threads_exceptionptr@l
1085 # endif
1086 #endif
1087
1088         lwz     xptr,0(v0)            /* get the exception pointer                */
1089         li      itmp3,0
1090         stw     itmp3,0(v0)           /* clear the exception pointer              */
1091         b       asm_handle_exception
1092
1093
1094 asm_cacheflush:
1095         add     r4,r3,r4
1096         rlwinm  r3,r3,0,0,26
1097         addi    r4,r4,31
1098         rlwinm  r4,r4,0,0,26
1099         mr      r5,r3
1100 1:
1101         cmplw   r3,r4
1102         bge     0f
1103         dcbst   0,r3
1104         addi    r3,r3,32
1105         b       1b
1106 0:
1107         sync
1108 1:
1109         cmplw   r5,r4
1110         bge     0f
1111         icbi    0,r5
1112         addi    r5,r5,32
1113         b       1b
1114 0:
1115         sync
1116         isync
1117         blr
1118
1119
1120         .align 3
1121 doublezero:
1122         .double 0.0
1123
1124 asm_initialize_thread_stack:
1125         addi r4,r4,-256
1126         stw r3,120(r4)
1127         li r3,0
1128         stw r3,124(r4)
1129         stw r3,0(r4)
1130         stw r3,4(r4)
1131         stw r3,8(r4)
1132         stw r3,12(r4)
1133         stw r3,16(r4)
1134         stw r3,20(r4)
1135         stw r3,24(r4)
1136         stw r3,28(r4)
1137         stw r3,32(r4)
1138         stw r3,36(r4)
1139
1140         stw r3,128(r4)
1141         stw r3,132(r4)
1142         stw r3,136(r4)
1143         stw r3,140(r4)
1144         stw r3,144(r4)
1145         stw r3,148(r4)
1146         stw r3,152(r4)
1147         stw r3,156(r4)
1148
1149         mflr r0
1150         bl 0f
1151 0:
1152         mflr r3
1153         mtlr r0
1154 #if defined(__DARWIN__)
1155         lfd fr0,lo16(doublezero-0b)(r3)
1156 #else
1157         lfd fr0,(doublezero-0b)@l(r3)
1158 #endif
1159
1160         stfd fr0,40(r4)
1161         stfd fr0,48(r4)
1162         stfd fr0,56(r4)
1163         stfd fr0,64(r4)
1164         stfd fr0,72(r4)
1165         stfd fr0,80(r4)
1166         stfd fr0,88(r4)
1167         stfd fr0,96(r4)
1168         stfd fr0,104(r4)
1169         stfd fr0,112(r4)
1170
1171         stfd fr0,160(r4)
1172         stfd fr0,168(r4)
1173         stfd fr0,176(r4)
1174         stfd fr0,184(r4)
1175         stfd fr0,192(r4)
1176         stfd fr0,200(r4)
1177         stfd fr0,208(r4)
1178         stfd fr0,216(r4)
1179
1180         mr r3,r4
1181         blr
1182
1183
1184 asm_perform_threadswitch:
1185         mflr r0
1186         addi r1,r1,-224
1187         stw r0,120(r1)
1188         stw pv,124(r1)
1189         stw r14,0(r1)
1190         stw r15,4(r1)
1191         stw r24,8(r1)
1192         stw r25,12(r1)
1193         stw r26,16(r1)
1194         stw r27,20(r1)
1195         stw r28,24(r1)
1196         stw r29,28(r1)
1197         stw r30,32(r1)
1198         stw r31,36(r1)
1199         stfd fr14,40(r1)
1200         stfd fr15,48(r1)
1201         stfd fr24,56(r1)
1202         stfd fr25,64(r1)
1203         stfd fr26,72(r1)
1204         stfd fr27,80(r1)
1205         stfd fr28,88(r1)
1206         stfd fr29,96(r1)
1207         stfd fr30,104(r1)
1208         stfd fr31,112(r1)
1209
1210         stw r16,128(r1)
1211         stw r17,132(r1)
1212         stw r18,136(r1)
1213         stw r19,140(r1)
1214         stw r20,144(r1)
1215         stw r21,148(r1)
1216         stw r22,152(r1)
1217         stw r23,156(r1)
1218         stfd fr16,160(r1)
1219         stfd fr17,168(r1)
1220         stfd fr18,176(r1)
1221         stfd fr19,184(r1)
1222         stfd fr20,192(r1)
1223         stfd fr21,200(r1)
1224         stfd fr22,208(r1)
1225         stfd fr23,216(r1)
1226
1227         stw r1,0(r3)
1228         stw r1,0(r5)
1229         lwz r1,0(r4)
1230
1231         lwz r0,120(r1)
1232         lwz pv,124(r1)
1233         lwz r14,0(r1)
1234         lwz r15,4(r1)
1235         lwz r24,8(r1)
1236         lwz r25,12(r1)
1237         lwz r26,16(r1)
1238         lwz r27,20(r1)
1239         lwz r28,24(r1)
1240         lwz r29,28(r1)
1241         lwz r30,32(r1)
1242         lwz r31,36(r1)
1243         lfd fr14,40(r1)
1244         lfd fr15,48(r1)
1245         lfd fr24,56(r1)
1246         lfd fr25,64(r1)
1247         lfd fr26,72(r1)
1248         lfd fr27,80(r1)
1249         lfd fr28,88(r1)
1250         lfd fr29,96(r1)
1251         lfd fr30,104(r1)
1252         lfd fr31,112(r1)
1253
1254         lwz r16,128(r1)
1255         lwz r17,132(r1)
1256         lwz r18,136(r1)
1257         lwz r19,140(r1)
1258         lwz r20,144(r1)
1259         lwz r21,148(r1)
1260         lwz r22,152(r1)
1261         lwz r23,156(r1)
1262         lfd fr16,160(r1)
1263         lfd fr17,168(r1)
1264         lfd fr18,176(r1)
1265         lfd fr19,184(r1)
1266         lfd fr20,192(r1)
1267         lfd fr21,200(r1)
1268         lfd fr22,208(r1)
1269         lfd fr23,216(r1)
1270
1271         mtlr r0
1272         addi r1,r1,224
1273         blr
1274
1275
1276 asm_switchstackandcall:
1277         mflr r0
1278         stwu r3,-48(r3)
1279         stw r0,40(r3)
1280         stw r1,44(r3)
1281         stw r1,0(r5)
1282         mr r1,r3
1283
1284         mtctr r4
1285         mr r3,r6
1286         bctrl
1287
1288         lwz r0,40(r1)
1289         mtlr r0
1290         lwz r1,44(r1)
1291         blr
1292
1293
1294 asm_getclassvalues_atomic:
1295 _crit_restart2:
1296 _crit_begin2:
1297         lwz     r6,offbaseval(r3)
1298         lwz     r7,offdiffval(r3)
1299         lwz     r8,offbaseval(r4)
1300 _crit_end2:
1301         stw     r6,offcast_super_baseval(r5)
1302         stw     r7,offcast_super_diffval(r5)
1303         stw     r8,offcast_sub_baseval(r5)
1304         blr
1305
1306         .data
1307
1308 asm_criticalsections:
1309 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1310         .long   _crit_begin1
1311         .long   _crit_end1
1312         .long   _crit_restart1
1313         .long   _crit_begin2
1314         .long   _crit_end2
1315         .long   _crit_restart2
1316 #endif
1317         .long 0
1318
1319
1320 /*
1321  * These are local overrides for various environment variables in Emacs.
1322  * Please do not remove this and leave it at the end of the file, where
1323  * Emacs will automagically detect them.
1324  * ---------------------------------------------------------------------
1325  * Local variables:
1326  * mode: asm
1327  * indent-tabs-mode: t
1328  * c-basic-offset: 4
1329  * tab-width: 4
1330  * End:
1331  */