* src/vm/jit/powerpc64/patcher.c
[cacao.git] / src / vm / jit / powerpc64 / asmpart.S
1 /* src/vm/jit/powerpc64/asmpart.S - Java-C interface functions for PowerPC64
2                 
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: asmpart.S 7909 2007-05-15 10:32:16Z tbfg $
26
27 */
28
29
30 #include "config.h"
31
32 #define __ASSEMBLY__
33
34 #include "md-abi.h"
35 #include "md-asm.h"
36
37 #include "vm/jit/abi-asm.h"
38 #include "vm/jit/methodheader.h"
39 #include "vm/jit/powerpc64/offsets.h"
40
41 .section ".toc","aw"
42 .section ".text"
43
44         .align 2        
45
46
47 /* export functions ***********************************************************/
48
49         .globl asm_vm_call_method_exception_handler
50         .globl asm_vm_call_method_end
51
52         .globl asm_call_jit_compiler
53
54         .globl asm_handle_nat_exception
55         .globl asm_handle_exception
56
57         .globl asm_abstractmethoderror
58
59         .globl asm_patcher_wrapper
60
61 #if defined(ENABLE_REPLACEMENT)
62         .globl asm_replacement_out
63         .globl .asm_replacement_in
64 #endif
65
66         .globl asm_cacheflush
67         .globl asm_criticalsections
68         .globl asm_getclassvalues_atomic
69
70
71 /* asm_vm_call_method **********************************************************
72 *                                                                              *
73 *   This function calls a Java-method (which possibly needs compilation)       *
74 *   with up to 4 address parameters.                                           *
75 *                                                                              *
76 *   This functions calls the JIT-compiler which eventually translates the      *
77 *   method into machine code.                                                  *
78 *                                                                              *
79 *   C-prototype:                                                               *
80 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
81 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
82 *                                                                              *
83 *******************************************************************************/
84         /* this is the method header see src/vm/jit/methodheader.h */
85
86         .align  8
87
88         .quad   0                           /* catch type all                     */
89         .quad   0                           /* handler pc                         */
90         .quad   0                           /* end pc                             */
91         .quad   0                           /* start pc                           */
92         .long   1                           /* extable size                       */
93         .long   0                           /* ALIGNMENT PADDING                  */
94         .quad   0                           /* line number table  start           */
95         .quad   0                           /* line number table  size            */
96         .long   0                           /* ALIGNMENT PADDING                  */
97         .long   0                           /* fltsave                            */
98         .long   0                           /* intsave                            */
99         .long   0                           /* isleaf                             */
100         .long   0                           /* IsSync                             */
101         .long   0                           /* frame size                         */
102         .quad   0                           /* codeinfo pointer                   */
103
104 #ifdef ENABLE_LIBJVM
105         
106         .globl asm_vm_call_method
107         .globl asm_vm_call_method_int
108         .globl asm_vm_call_method_long
109         .globl asm_vm_call_method_float
110         .globl asm_vm_call_method_double
111         .section ".opd","aw"
112         .align 3
113
114         asm_vm_call_method:
115         asm_vm_call_method_int:
116         asm_vm_call_method_long:
117         asm_vm_call_method_float:
118         asm_vm_call_method_double:
119                 .quad   .asm_vm_call_method,.TOC.@tocbase,0
120                 .previous
121                 .size asm_vm_call_method, 24
122                 .type .asm_vm_call_method,@function
123                 .globl .asm_vm_call_method
124 #else
125         asm_vm_call_method:
126         .globl asm_vm_call_method
127         asm_vm_call_method_int:
128         .globl asm_vm_call_method_int
129         asm_vm_call_method_long:
130         .globl asm_vm_call_method_long
131         asm_vm_call_method_float:
132         .globl asm_vm_call_method_float
133         asm_vm_call_method_double:
134         .globl asm_vm_call_method_double
135 #endif
136
137 .asm_vm_call_method:
138 .asm_vm_call_method_int:
139 .asm_vm_call_method_long:
140 .asm_vm_call_method_float:
141 .asm_vm_call_method_double:
142         mflr    r0
143         std     r0,LA_LR_OFFSET(sp)
144         stdu    sp,-40*8(sp)
145         
146         std     s0,8*8(sp)                /* save used callee saved registers     */
147         std     a0,9*8(sp)                /* save method pointer for compiler     */
148
149         std     pv,11*8(sp)               /* save PV register                     */
150
151         std     itmp3,12*8(sp)            /* registers r14-r31 are callee saved   */
152         stfd    ftmp1,13*8(sp)            /* registers f14-f31 are callee saved   */
153         stfd    ftmp2,14*8(sp)
154
155         SAVE_TEMPORARY_REGISTERS(15)     
156
157         mr      itmp2,a1                  /* arg count                            */
158         mr      itmp1,a2                  /* pointer to arg block                 */
159
160         mr      t4,itmp2                  /* save argument count                  */
161         mr      t5,itmp1                  /* save argument block pointer          */
162
163         mr      s0,sp                     /* save current sp to s0                */
164
165         addi    itmp1,itmp1,-sizevmarg    /* initialize pointer (smaller code)    */
166         addi    itmp2,itmp2,1             /* initialize argument count            */
167         li      t0,0                      /* initialize integer argument counter  */
168         li      t1,0                      /* initialize float argument counter    */
169         li      t6,0                      /* initialize integer register counter  */
170         li      t3,8                      /* initialize PA counter*/
171
172 L_register_copy:
173         addi    itmp1,itmp1,sizevmarg     /* goto next argument block             */
174         addi    itmp2,itmp2,-1            /* argument count - 1                   */
175         mr.     itmp2,itmp2
176         beq     L_register_copy_done
177
178         addi    t3,t3,-1                  /* uses a PA slot                       */
179         lwz     itmp3,offvmargtype+4(itmp1)
180         andi.   r0,itmp3,0x0002           /* is this a float/double type?         */
181         bne     L_register_handle_float
182         
183 L_register_handle_int:
184         cmpwi   t6,INT_ARG_CNT            /* are we out of integer argument       */
185         beq     L_register_copy           /* registers? yes, next loop            */
186
187         cmpwi   itmp3,0x0004              /* is it TYPE_ADR? */
188         beq     L_register_handle_long
189
190         andi.   r0,itmp3,0x0001           /* is this a 2-word type?               */
191         bne     L_register_handle_long
192
193         lis     itmp3,L_jumptable_int@highest           /* load 64bit address   */
194         ori     itmp3,itmp3,L_jumptable_int@higher
195         rldicr  itmp3,itmp3,32,31
196         oris    itmp3,itmp3,L_jumptable_int@h
197         ori     itmp3,itmp3,L_jumptable_int@l
198         b       L_register_do_copy_longint
199
200 L_register_handle_long:
201
202         lis     itmp3,L_jumptable_long@highest          /* load 64bit address   */
203         ori     itmp3,itmp3,L_jumptable_long@higher
204         rldicr  itmp3,itmp3,32,31
205         oris    itmp3,itmp3,L_jumptable_long@h
206         ori     itmp3,itmp3,L_jumptable_long@l
207
208 L_register_do_copy_longint:
209         slwi    t2,t6,3                   /* multiple of 8-bytes                  */
210         add     itmp3,itmp3,t2            /* calculate address of jumptable       */
211         ld      itmp3,0(itmp3)            /* load function address                */
212         mtctr   itmp3
213         addi    t0,t0,1                   /* integer argument counter             */
214         addi    t6,t6,1                   /* integer argument register counter    */
215         bctr
216
217 L_register_handle_float:
218         cmpwi   t1,FLT_ARG_CNT            /* are we out of float argument         */
219         beq     L_register_copy           /* registers? yes, next loop            */
220
221         andi.   r0,itmp3,0x0001           /* is this a 2-word type?               */
222         bne     L_register_handle_double
223
224         lis     itmp3,L_jumptable_float@highest         /* load 64bit address   */
225         ori     itmp3,itmp3,L_jumptable_float@higher
226         rldicr  itmp3,itmp3,32,31
227         oris    itmp3,itmp3,L_jumptable_float@h
228         ori     itmp3,itmp3,L_jumptable_float@l
229         b L_register_do_copy_floatdouble
230
231 L_register_handle_double:
232
233         lis     itmp3,L_jumptable_double@highest                /* load 64bit address   */
234         ori     itmp3,itmp3,L_jumptable_double@higher
235         rldicr  itmp3,itmp3,32,31
236         oris    itmp3,itmp3,L_jumptable_double@h
237         ori     itmp3,itmp3,L_jumptable_double@l
238
239
240 L_register_do_copy_floatdouble:
241
242         slwi    t2,t1,3                   /* multiple of 8-bytes                  */
243         add     itmp3,itmp3,t2            /* calculate address of jumptable       */
244         ld      itmp3,0(itmp3)            /* load function address                */
245         mtctr   itmp3
246         addi    t1,t1,1                   /* float argument counter               */
247         mr.     t3,t3                     /* are we still in PA ?                 */
248         blt     L_float_not_uses_PA 
249         addi    t6,t6,1                   /* if so it uses an interger arg reg    */
250 L_float_not_uses_PA:
251         bctr
252
253
254 L_register_copy_done:
255         subi    sp,sp,PA_SIZE             /* PA_SIZE are used by definition       */
256                                           /* calculate remaining arguments        */
257         sub     itmp3,t4,t0               /* - integer arguments in registers     */
258         sub     itmp3,itmp3,t1            /* - float arguments in registers       */
259         mr.     itmp3,itmp3
260         beq     L_stack_copy_done
261
262         mr      itmp2,t4                  /* restore argument count               */
263         mr      itmp1,t5                  /* restore argument block pointer       */
264
265         slwi    t4,itmp3,3                /* XXX use 8-bytes slots for now        */
266         addi    t4,t4,LA_SIZE             /* add size of linkage area             */
267         sub     sp,sp,t4
268
269         mr      t6,sp                     /* use t6 as temporary sp               */
270         addi    t6,t6,LA_SIZE             /* skip linkage area                    */
271
272         addi    itmp1,itmp1,-sizevmarg    /* initialize pointer (smaller code)    */
273         addi    itmp2,itmp2,1             /* initialize argument count            */
274         li      t3,8                      /* initialize PA counter                */
275         addi    t6,t6,-8                  /* make code simpler                    */
276         
277 L_stack_copy_loop:
278         addi    itmp1,itmp1,sizevmarg     /* goto next argument block             */
279         addi    itmp2,itmp2,-1            /* argument count - 1                   */
280         mr.     itmp2,itmp2
281         beq     L_stack_copy_done
282         addi    t6,t6,8                   /* increase stack */
283 L_stack_not_uses_PA:
284
285         lwz     itmp3,offvmargtype+4(itmp1)
286         andi.   r0,itmp3,0x0002           /* is this a float/double type?         */
287         bne     L_stack_handle_float
288
289 L_stack_handle_int:
290         addi    t0,t0,-1                  /* arguments assigned to registers      */
291         mr.     t0,t0
292         bge     L_stack_copy_loop
293
294         andi.   r0,itmp3,0x0001           /* is this a 2-word type?               */
295         bne     L_stack_handle_long
296
297         lwa     itmp3,offvmargdata+4(itmp1) /* get integer argument               */
298         std     itmp3,0(t6)               /* and store it on the stack            */
299         b       L_stack_copy_loop
300
301 L_stack_handle_long:
302         ld      itmp3,offvmargdata+0(itmp1) /* get long argument                  */
303         std     itmp3,0(t6)               /* and store it on the stack            */
304         b       L_stack_copy_loop
305                 
306 L_stack_handle_float:
307         addi    t1,t1,-1                  /* arguments assigned to registers      */
308         mr.     t1,t1
309         bge     L_stack_copy_loop
310
311         andi.   r0,itmp3,0x0001           /* is this a 2-word type?               */
312         bne     L_stack_handle_double
313
314         lfs     ftmp3,offvmargdata(itmp1) /* get float argument                   */
315         stfd    ftmp3,0(t6)               /* and store it on the stack            */
316         b       L_stack_copy_loop
317
318 L_stack_handle_double:
319         lfd     ftmp3,offvmargdata(itmp1) /* get double argument                  */
320         stfd    ftmp3,0(t6)               /* and store it on the stack            */
321         b       L_stack_copy_loop
322
323 L_stack_copy_done:
324         ld      itmp1,9*8(s0)             /* pass method pointer via tmp1         */
325
326         lis     mptr,L_asm_call_jit_compiler@highest    /* load 64bit address   */
327         ori     mptr,mptr,L_asm_call_jit_compiler@higher
328         rldicr  mptr,mptr,32,31
329         oris    mptr,mptr,L_asm_call_jit_compiler@h
330         ori     mptr,mptr,L_asm_call_jit_compiler@l
331         std     mptr,7*8(s0)
332         addi    mptr,s0,7*8
333
334         ld      pv,0*8(mptr)
335         mtctr   pv
336         bctrl
337 1:
338         mflr    itmp1
339
340         addi    pv,itmp1,(.asm_vm_call_method - 1b)@l
341
342 L_asm_vm_call_method_return:
343         mr      sp,s0                     /* restore the function's sp            */
344
345         ld      s0,8*8(sp)                /* restore used callee saved registers  */
346
347         ld      pv,11*8(sp)               /* save PV register                     */
348
349         ld      itmp3,12*8(sp)
350         lfd     ftmp1,13*8(sp)            /* registers f14-f31 are callee saved   */
351         lfd     ftmp2,14*8(sp)
352
353         RESTORE_TEMPORARY_REGISTERS(15) 
354
355         ld     r0,40*8+LA_LR_OFFSET(r1)
356         mtlr   r0
357         addi   r1,r1,40*8
358         blr
359
360 asm_vm_call_method_exception_handler:
361         mr      r3,itmp1
362         bl      builtin_throw_exception
363         b       L_asm_vm_call_method_return
364
365
366         .data
367         .align  8
368
369 L_jumptable_int:
370         .quad   L_handle_a0
371         .quad   L_handle_a1
372         .quad   L_handle_a2
373         .quad   L_handle_a3
374         .quad   L_handle_a4
375         .quad   L_handle_a5
376         .quad   L_handle_a6
377         .quad   L_handle_a7
378
379         .text
380         .align  4
381
382 L_handle_a0:
383         lwa     a0,offvmargdata+4(itmp1)
384         b       L_register_copy
385 L_handle_a1:
386         lwa     a1,offvmargdata+4(itmp1)
387         b       L_register_copy
388 L_handle_a2:
389         lwa     a2,offvmargdata+4(itmp1)
390         b       L_register_copy
391 L_handle_a3:
392         lwa     a3,offvmargdata+4(itmp1)
393         b       L_register_copy
394 L_handle_a4:
395         lwa     a4,offvmargdata+4(itmp1)
396         b       L_register_copy
397 L_handle_a5:
398         lwa     a5,offvmargdata+4(itmp1)
399         b       L_register_copy
400 L_handle_a6:
401         lwa     a6,offvmargdata+4(itmp1)
402         b       L_register_copy
403 L_handle_a7:
404         lwa     a7,offvmargdata+4(itmp1)
405         b       L_register_copy
406
407
408         .data
409         .align  8
410
411 L_jumptable_long:
412         .quad   L_handle_a0l
413         .quad   L_handle_a1l
414         .quad   L_handle_a2l
415         .quad   L_handle_a3l
416         .quad   L_handle_a4l
417         .quad   L_handle_a5l
418         .quad   L_handle_a6l
419         .quad   L_handle_a7l
420
421         .text
422         .align  4
423
424 L_handle_a0l:
425         ld     a0,offvmargdata(itmp1)
426         b       L_register_copy
427 L_handle_a1l:
428         ld     a1,offvmargdata(itmp1)
429         b       L_register_copy
430 L_handle_a2l:
431         ld     a2,offvmargdata(itmp1)
432         b       L_register_copy
433 L_handle_a3l:
434         ld     a3,offvmargdata(itmp1)
435         b       L_register_copy
436 L_handle_a4l:
437         ld     a4,offvmargdata(itmp1)
438         b       L_register_copy
439 L_handle_a5l:
440         ld     a5,offvmargdata(itmp1)
441         b       L_register_copy
442 L_handle_a6l:
443         ld     a6,offvmargdata(itmp1)
444         b       L_register_copy
445 L_handle_a7l:
446         ld     a7,offvmargdata(itmp1)
447         b       L_register_copy
448
449         .data
450         .align  8
451
452 L_jumptable_float:
453         .quad   L_handle_fa0
454         .quad   L_handle_fa1
455         .quad   L_handle_fa2
456         .quad   L_handle_fa3
457         .quad   L_handle_fa4
458         .quad   L_handle_fa5
459         .quad   L_handle_fa6
460         .quad   L_handle_fa7
461         .quad   L_handle_fa8
462         .quad   L_handle_fa9
463         .quad   L_handle_fa10
464         .quad   L_handle_fa11
465         .quad   L_handle_fa12
466
467         .text
468         .align  4
469
470 L_handle_fa0:
471         lfs     fa0,offvmargdata(itmp1)
472         b       L_register_copy
473 L_handle_fa1:
474         lfs     fa1,offvmargdata(itmp1)
475         b       L_register_copy
476 L_handle_fa2:
477         lfs     fa2,offvmargdata(itmp1)
478         b       L_register_copy
479 L_handle_fa3:
480         lfs     fa3,offvmargdata(itmp1)
481         b       L_register_copy
482 L_handle_fa4:
483         lfs     fa4,offvmargdata(itmp1)
484         b       L_register_copy
485 L_handle_fa5:
486         lfs     fa5,offvmargdata(itmp1)
487         b       L_register_copy
488 L_handle_fa6:
489         lfs     fa6,offvmargdata(itmp1)
490         b       L_register_copy
491 L_handle_fa7:
492         lfs     fa7,offvmargdata(itmp1)
493         b       L_register_copy
494 L_handle_fa8:
495         lfs     fa8,offvmargdata(itmp1)
496         b       L_register_copy
497 L_handle_fa9:
498         lfs     fa9,offvmargdata(itmp1)
499         b       L_register_copy
500 L_handle_fa10:
501         lfs     fa10,offvmargdata(itmp1)
502         b       L_register_copy
503 L_handle_fa11:
504         lfs     fa11,offvmargdata(itmp1)
505         b       L_register_copy
506 L_handle_fa12:
507         lfs     fa12,offvmargdata(itmp1)
508         b       L_register_copy
509
510         .data
511         .align  8
512
513 L_jumptable_double:
514         .quad   L_handle_fda0
515         .quad   L_handle_fda1
516         .quad   L_handle_fda2
517         .quad   L_handle_fda3
518         .quad   L_handle_fda4
519         .quad   L_handle_fda5
520         .quad   L_handle_fda6
521         .quad   L_handle_fda7
522         .quad   L_handle_fda8
523         .quad   L_handle_fda9
524         .quad   L_handle_fda10
525         .quad   L_handle_fda11
526         .quad   L_handle_fda12
527
528         .text
529         .align  4
530
531 L_handle_fda0:
532         lfd     fa0,offvmargdata(itmp1)
533         b       L_register_copy
534 L_handle_fda1:
535         lfd     fa1,offvmargdata(itmp1)
536         b       L_register_copy
537 L_handle_fda2:
538         lfd     fa2,offvmargdata(itmp1)
539         b       L_register_copy
540 L_handle_fda3:
541         lfd     fa3,offvmargdata(itmp1)
542         b       L_register_copy
543 L_handle_fda4:
544         lfd     fa4,offvmargdata(itmp1)
545         b       L_register_copy
546 L_handle_fda5:
547         lfd     fa5,offvmargdata(itmp1)
548         b       L_register_copy
549 L_handle_fda6:
550         lfd     fa6,offvmargdata(itmp1)
551         b       L_register_copy
552 L_handle_fda7:
553         lfd     fa7,offvmargdata(itmp1)
554         b       L_register_copy
555 L_handle_fda8:
556         lfd     fa8,offvmargdata(itmp1)
557         b       L_register_copy
558 L_handle_fda9:
559         lfd     fa9,offvmargdata(itmp1)
560         b       L_register_copy
561 L_handle_fda10:
562         lfd     fa10,offvmargdata(itmp1)
563         b       L_register_copy
564 L_handle_fda11:
565         lfd     fa11,offvmargdata(itmp1)
566         b       L_register_copy
567 L_handle_fda12:
568         lfd     fa12,offvmargdata(itmp1)
569         b       L_register_copy
570
571 asm_vm_call_method_end:
572         nop
573
574 /* asm_call_jit_compiler *******************************************************
575
576    Invokes the compiler for untranslated JavaVM methods.
577
578 *******************************************************************************/
579
580 asm_call_jit_compiler:
581 L_asm_call_jit_compiler:                /* required for PIC code              */
582         mflr    r0
583         std     r0,LA_LR_OFFSET(sp)         /* save return address                */
584         stdu    r1,-(LA_SIZE+PA_SIZE+ARG_CNT*8)(sp)
585
586         SAVE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS)
587
588         mr      a0,itmp1
589         mr      a1,mptr
590         addi    a2,sp,(LA_SIZE + PA_SIZE+ ARG_CNT*8)
591         ld      a3,(LA_SIZE + PA_SIZE + ARG_CNT*8)+LA_LR_OFFSET(sp)
592         bl      jit_asm_compile
593         ori     r0,r0,0                     /* nop needed after jump to function desc. */
594         mr      pv,v0                       /* move address to pv register        */
595
596         RESTORE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS)
597
598         ld     itmp1,(LA_SIZE + PA_SIZE + ARG_CNT*8)+LA_LR_OFFSET(sp)
599         mtlr   itmp1
600
601         addi    sp,sp,(LA_SIZE + PA_SIZE + ARG_CNT*8)
602
603         mr.     pv,pv                       /* test for exception                 */
604         beq     L_asm_call_jit_compiler_exception
605
606         mtctr   pv                          /* move method address to control reg */
607         bctr                                /* and call the Java method           */
608
609 L_asm_call_jit_compiler_exception:
610         mflr    r0
611         std     r0,LA_LR_OFFSET(sp)
612         stdu    sp,-LA_SIZE_ALIGNED(sp)     /* preserve linkage area              */
613         bl      exceptions_get_and_clear_exception
614         ld      xpc,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
615         mtlr    xpc     
616         addi    sp,sp,LA_SIZE_ALIGNED
617
618         mr      xptr,v0                     /* get exception                      */
619         addi    xpc,xpc,-4                  /* exception address is ra - 4        */
620         b       L_asm_handle_nat_exception
621
622
623 /********************* function asm_handle_exception ***************************
624 *                                                                              *
625 *   This function handles an exception. It does not use the usual calling      *
626 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
627 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
628 *   the local exception table for a handler. If no one is found, it unwinds    *
629 *   stacks and continues searching the callers.                                *
630 *                                                                              *
631 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
632 *                                                                              *
633 *******************************************************************************/
634                 
635 asm_handle_nat_exception:
636 L_asm_handle_nat_exception:             /* required for PIC code              */
637 L_asm_handle_exception_stack_loop:
638         mflr    r0
639         addi    sp,sp,-(LA_SIZE+PA_SIZE+((4+6)*8))  /* allocate stack (+4 for darwin)     */
640         std     xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp)    /* save exception pointer             */
641         std     xpc,LA_SIZE+PA_SIZE+(4+1)*8(sp)     /* save exception pc                  */
642         std     r0,LA_SIZE+PA_SIZE+(4+3)*8(sp)      /* save return address                */
643         li      itmp3,0
644         std     itmp3,LA_SIZE+PA_SIZE+(4+4)*8(sp)   /* save maybe-leaf flag (cleared)     */
645
646         mr      a0,r0                       /* pass return address                */
647         bl      md_codegen_get_pv_from_pc   /* get PV from RA                     */
648         std     v0,LA_SIZE+PA_SIZE+(4+2)*8(sp)      /* save data segment pointer          */
649
650         ld      a0,LA_SIZE+PA_SIZE+(4+0)*8(sp)      /* pass xptr                          */
651         ld      a1,LA_SIZE+PA_SIZE+(4+1)*8(sp)      /* pass xpc                           */
652         ld      a2,LA_SIZE+PA_SIZE+(4+2)*8(sp)      /* pass PV (v0 == a0)                 */
653         addi    a3,sp,LA_SIZE+PA_SIZE+((4+6)*8)     /* pass Java SP                       */
654
655         b       L_asm_handle_exception_continue
656
657
658 asm_handle_exception:
659 L_asm_handle_exception:                 /* required for PIC code              */
660         addi    sp,sp,-(ARG_CNT+TMP_CNT)*8  /* create maybe-leaf stackframe       */
661
662         SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
663         SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
664
665         addi    sp,sp,-(LA_SIZE+PA_SIZE+(4+6)*8)        /* allocate stack                     */
666         std     xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp)        /* save exception pointer             */
667         std     pv,LA_SIZE+PA_SIZE+(4+2)*8(sp)          /* save data segment pointer          */
668         mflr    r0                                      /* save return address                */
669         std     r0,LA_SIZE+PA_SIZE+(4+3)*8(sp)          
670         li      t0, 1
671         std     t0, LA_SIZE+PA_SIZE+(4+4)*8(sp)         /* maybe-leaf flag */
672         
673         mr      a0,xptr                     /* pass exception pointer             */
674         mr      a1,xpc                      /* pass exception pc                  */
675         mr      a2,pv                       /* pass data segment pointer          */
676         addi    a3,sp,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+(4+6)*8
677
678
679 L_asm_handle_exception_continue:
680         bl      exceptions_handle_exception
681
682         mr.     v0,v0
683         beq     L_asm_handle_exception_not_catched
684
685         mr      xpc,v0                              /* move handlerpc into xpc            */
686         ld      xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp)    /* restore exception pointer          */
687         ld      pv,LA_SIZE+PA_SIZE+(4+2)*8(sp)      /* restore data segment pointer       */
688         ld      r0,LA_SIZE+PA_SIZE+(4+3)*8(sp)      /* restore return address             */
689         mtlr    r0
690         ld      t0,LA_SIZE+PA_SIZE+(4+4)*8(sp)      /* get maybe-leaf flag                */
691         addi    sp,sp,LA_SIZE+PA_SIZE+(4+6)*8       /* free stack frame                   */
692
693         mr.     t0,t0
694         beq     L_asm_handle_exception_no_leaf
695
696         RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
697         RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
698
699         addi    sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
700
701 L_asm_handle_exception_no_leaf:
702         mtctr   xpc                         /* jump to the handler                */
703         bctr
704
705 L_asm_handle_exception_not_catched:
706         ld      xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp)        /* restore exception pointer          */
707         ld      pv,LA_SIZE+PA_SIZE+(4+2)*8(sp)          /* restore data segment pointer       */
708         ld      r0,LA_SIZE+PA_SIZE+(4+3)*8(sp)          /* restore return address             */
709         mtlr    r0
710         ld      t0,LA_SIZE+PA_SIZE+(4+4)*8(sp)          /* get maybe-leaf flag                */
711         addi    sp,sp,LA_SIZE+PA_SIZE+(4+6)*8           /* free stack frame                   */
712
713         mr.     t0,t0
714         beq     L_asm_handle_exception_no_leaf_stack
715
716         addi    sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
717         li      t0,0                        /* clear the maybe-leaf flag          */
718
719 L_asm_handle_exception_no_leaf_stack:
720         lwz     t1,FrameSize(pv)            /* get frame size                     */
721         add     t1,sp,t1                    /* pointer to save area               */
722
723         lwz     t2,IsLeaf(pv)               /* is leaf procedure                  */
724         mr.     t2,t2
725         bne     L_asm_handle_exception_no_ra_restore
726
727         ld      r0,LA_LR_OFFSET(t1)         /* restore ra                         */
728         mtlr    r0
729
730 L_asm_handle_exception_no_ra_restore:
731         mflr    xpc                         /* the new xpc is ra                  */
732         mr      t4,xpc                      /* save RA */
733         lwz     t2,IntSave(pv)              /* t1 = saved int register count      */
734         bl      ex_int1
735 ex_int1:
736         mflr    t3                          /* t3 = current pc                    */
737         addi    t3,t3,(ex_int2-ex_int1)@l
738         slwi    t2,t2,2                     /* t2 = register count * 4            */
739         subf    t3,t2,t3                    /* t3 = IntSave - t2                  */
740         mtctr   t3
741         bctr
742
743         ld      s0,-9*8(t1)
744         ld      s1,-8*8(t1)
745         ld      s2,-7*8(t1)
746         ld      s3,-6*8(t1)
747         ld      s4,-5*8(t1)
748         ld      s5,-4*8(t1)
749         ld      s6,-3*8(t1)
750         ld      s7,-2*8(t1)
751         ld      s8,-1*8(t1)
752
753 ex_int2:
754         subf    t1,t2,t1                    /* t1 = t1 - register count * 4       */
755         lwz     t2,FltSave(pv)
756         bl      ex_flt1
757 ex_flt1:
758         mflr    t3
759         addi    t3,t3,(ex_flt2-ex_flt1)@l
760         slwi    t2,t2,2                     /* t2 = register count * 4            */
761         subf    t3,t2,t3                    /* t3 = FltSave - t2                  */
762         mtctr   t3
763         bctr
764
765         lfd     fs0,-10*8(t1)
766         lfd     fs1,-9*8(t1)
767         lfd     fs2,-8*8(t1)
768         lfd     fs3,-7*8(t1)
769         lfd     fs4,-6*8(t1)
770         lfd     fs5,-5*8(t1)
771         lfd     fs6,-4*8(t1)
772         lfd     fs7,-3*8(t1)
773         lfd     fs8,-2*8(t1)
774         lfd     fs9,-1*8(t1)
775
776 ex_flt2:
777         mtlr    t4                                   /* restore RA */
778         lwz     t1,FrameSize(pv)                     
779         add     sp,sp,t1                             /* unwind stack */
780         b       L_asm_handle_exception_stack_loop
781
782
783 /* asm_abstractmethoderror *****************************************************
784
785    Creates and throws an AbstractMethodError.
786
787 *******************************************************************************/
788
789 asm_abstractmethoderror:
790         mflr    r0
791         std     r0,LA_LR_OFFSET(sp)
792         stdu    sp,-LA_SIZE_ALIGNED(sp)     /* preserve linkage area              */
793         addi    a0,sp,LA_SIZE_ALIGNED       /* pass java sp                       */
794         mr      a1,r0                       /* pass exception address             */
795         bl      exceptions_asm_new_abstractmethoderror
796         ld      r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
797         mtlr    r0                          /* restore return address             */
798         addi    sp,sp,LA_SIZE_ALIGNED
799
800         mr      xptr,v0                     /* get exception pointer              */
801         mr      xpc,r0                      /* we can't use r0 directly in addi   */
802         addi    xpc,xpc,-4                  /* exception address is ra - 4        */
803         b       L_asm_handle_nat_exception
804
805
806 /* asm_patcher_wrapper *********************************************************
807
808    XXX
809
810    Stack layout:
811      40   return address into JIT code (patch position)
812      32   pointer to virtual java_objectheader
813      24   machine code (which is patched back later)
814      16   unresolved class/method/field reference
815       8   data segment displacement from load instructions
816       0   patcher function pointer to call (pv is saved here afterwards)
817
818 *******************************************************************************/
819
820 asm_patcher_wrapper:
821         mflr    r0                    /* get Java return address (leaf)           */
822         std     r0,6*8(sp)            /* store it in the stub stackframe          */
823                                       /* keep stack 16-bytes aligned: 6+1+37 = 44 */
824         stdu    sp,-(LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8)(sp)
825
826         SAVE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS) /* save 8 int/8 float arguments   */
827         SAVE_TEMPORARY_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS+ARG_CNT)
828
829         std     itmp1,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+1*8(sp)
830         std     itmp2,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+2*8(sp)
831         std     pv,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+3*8(sp)
832
833         addi    a0,sp,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8      /* pass SP of patcher stub            */
834         mr      a1,pv                       /* pass PV                            */
835         mr      a2,r0                       /* pass RA (correct for leafs)        */
836         bl      patcher_wrapper
837         std     v0,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+4*8(sp)     /* save return value                  */
838
839
840         RESTORE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS) /* restore 8 int/8 float args  */
841         RESTORE_TEMPORARY_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS+ARG_CNT)
842
843         ld     itmp1,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+1*8(sp)
844         ld     itmp2,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+2*8(sp)
845         ld     pv,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+3*8(sp)
846         ld     itmp3,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+4*8(sp)
847
848         ld      r0,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+6*8(sp) /* restore RA                      */
849         mtlr    r0
850
851         mr.     itmp3,itmp3           /* check for an exception                   */
852         bne     L_asm_patcher_wrapper_exception
853
854                                       /* get return address (into JIT code)       */
855         ld     itmp3,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+5*8(sp)
856
857                                       /* remove stack frame + patcher stub stack  */
858         addi    sp,sp,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+8*8
859
860         mtctr   itmp3
861         bctr                          /* jump to new patched code                 */
862
863 L_asm_patcher_wrapper_exception:
864         mr      xptr,itmp3                  /* get exception                      */
865         ld      xpc,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+5*8(sp)
866         addi    sp,sp,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+8*8
867         b       L_asm_handle_exception
868
869 #if defined(ENABLE_REPLACEMENT)
870
871 /* asm_replacement_out *********************************************************
872
873    This code is jumped to from the replacement-out stubs that are executed
874    when a thread reaches an activated replacement point.
875
876    The purpose of asm_replacement_out is to read out the parts of the
877    execution state that cannot be accessed from C code, store this state,
878    and then call the C function replace_me.
879
880    Stack layout:
881       16                start of stack inside method to replace
882       0   rplpoint *    info on the replacement point that was reached
883
884    NOTE: itmp3 has been clobbered by the replacement-out stub!
885
886 *******************************************************************************/
887
888 /* some room to accomodate changes of the stack frame size during replacement */
889         /* XXX we should find a cleaner solution here */
890 #define REPLACEMENT_ROOM  512
891
892 asm_replacement_out:
893     /* create stack frame */
894         addi    sp,sp,-(sizeexecutionstate + REPLACEMENT_ROOM) /* XXX align */
895
896         /* save link register */
897         mflr    r16
898
899         /* save registers in execution state */
900         std     r0 ,( 0*8+offes_intregs)(sp)
901         std     r1 ,( 1*8+offes_intregs)(sp)
902         std     r2 ,( 2*8+offes_intregs)(sp)
903         std     r3 ,( 3*8+offes_intregs)(sp)
904         std     r4 ,( 4*8+offes_intregs)(sp)
905         std     r5 ,( 5*8+offes_intregs)(sp)
906         std     r6 ,( 6*8+offes_intregs)(sp)
907         std     r7 ,( 7*8+offes_intregs)(sp)
908         std     r8 ,( 8*8+offes_intregs)(sp)
909         std     r9 ,( 9*8+offes_intregs)(sp)
910         std     r10,(10*8+offes_intregs)(sp)
911         std     r11,(11*8+offes_intregs)(sp)
912         std     r12,(12*8+offes_intregs)(sp)
913         std     r13,(13*8+offes_intregs)(sp)
914         std     r14,(14*8+offes_intregs)(sp)
915         std     r15,(15*8+offes_intregs)(sp)
916         std     r16,(16*8+offes_intregs)(sp) /* link register */
917         std     r17,(17*8+offes_intregs)(sp)
918         std     r18,(18*8+offes_intregs)(sp)
919         std     r19,(19*8+offes_intregs)(sp)
920         std     r20,(20*8+offes_intregs)(sp)
921         std     r21,(21*8+offes_intregs)(sp)
922         std     r22,(22*8+offes_intregs)(sp)
923         std     r23,(23*8+offes_intregs)(sp)
924         std     r24,(24*8+offes_intregs)(sp)
925         std     r25,(25*8+offes_intregs)(sp)
926         std     r26,(26*8+offes_intregs)(sp)
927         std     r27,(27*8+offes_intregs)(sp)
928         std     r28,(28*8+offes_intregs)(sp)
929         std     r29,(29*8+offes_intregs)(sp)
930         std     r30,(30*8+offes_intregs)(sp)
931         std     r31,(31*8+offes_intregs)(sp)
932         
933         stfd    fr0 ,( 0*8+offes_fltregs)(sp)
934         stfd    fr1 ,( 1*8+offes_fltregs)(sp)
935         stfd    fr2 ,( 2*8+offes_fltregs)(sp)
936         stfd    fr3 ,( 3*8+offes_fltregs)(sp)
937         stfd    fr4 ,( 4*8+offes_fltregs)(sp)
938         stfd    fr5 ,( 5*8+offes_fltregs)(sp)
939         stfd    fr6 ,( 6*8+offes_fltregs)(sp)
940         stfd    fr7 ,( 7*8+offes_fltregs)(sp)
941         stfd    fr8 ,( 8*8+offes_fltregs)(sp)
942         stfd    fr9 ,( 9*8+offes_fltregs)(sp)
943         stfd    fr10,(10*8+offes_fltregs)(sp)
944         stfd    fr11,(11*8+offes_fltregs)(sp)
945         stfd    fr12,(12*8+offes_fltregs)(sp)
946         stfd    fr13,(13*8+offes_fltregs)(sp)
947         stfd    fr14,(14*8+offes_fltregs)(sp)
948         stfd    fr15,(15*8+offes_fltregs)(sp)
949         stfd    fr16,(16*8+offes_fltregs)(sp)
950         stfd    fr17,(17*8+offes_fltregs)(sp)
951         stfd    fr18,(18*8+offes_fltregs)(sp)
952         stfd    fr19,(19*8+offes_fltregs)(sp)
953         stfd    fr20,(20*8+offes_fltregs)(sp)
954         stfd    fr21,(21*8+offes_fltregs)(sp)
955         stfd    fr22,(22*8+offes_fltregs)(sp)
956         stfd    fr23,(23*8+offes_fltregs)(sp)
957         stfd    fr24,(24*8+offes_fltregs)(sp)
958         stfd    fr25,(25*8+offes_fltregs)(sp)
959         stfd    fr26,(26*8+offes_fltregs)(sp)
960         stfd    fr27,(27*8+offes_fltregs)(sp)
961         stfd    fr28,(28*8+offes_fltregs)(sp)
962         stfd    fr29,(29*8+offes_fltregs)(sp)
963         stfd    fr30,(30*8+offes_fltregs)(sp)
964         stfd    fr31,(31*8+offes_fltregs)(sp)
965         
966         /* calculate sp of method */
967         addi    itmp1,sp,(sizeexecutionstate + REPLACEMENT_ROOM + 4*4)
968         stw     itmp1,(offes_sp)(sp)
969
970         /* store pv */
971         stw     pv,(offes_pv)(sp)
972
973         /* call replace_me */
974         lwz     a0,-(4*4)(itmp1)            /* arg0: rplpoint *                   */
975         mr      a1,sp                       /* arg1: execution state              */
976         addi    sp,sp,-(LA_SIZE_ALIGNED)
977         b       replace_me                  /* call C function replace_me         */
978
979 /* asm_replacement_in **********************************************************
980
981    This code writes the given execution state and jumps to the replacement
982    code.
983
984    This function never returns!
985
986    NOTE: itmp3 is not restored!
987
988    C prototype:
989       void asm_replacement_in(executionstate *es);
990
991 *******************************************************************************/
992
993 .asm_replacement_in:
994         /* a0 == executionstate *es */
995
996         /* set new sp and pv */
997         ld     sp,(offes_sp)(a0)
998         ld     pv,(offes_pv)(a0)
999         
1000         /* copy registers from execution state */
1001         ld     r0 ,( 0*8+offes_intregs)(a0)
1002         /* r1 is sp                       */
1003         /* r2 is reserved                 */
1004         /* a0 is loaded below             */
1005         ld     r4 ,( 4*8+offes_intregs)(a0)
1006         ld     r5 ,( 5*8+offes_intregs)(a0)
1007         ld     r6 ,( 6*8+offes_intregs)(a0)
1008         ld     r7 ,( 7*8+offes_intregs)(a0)
1009         ld     r8 ,( 8*8+offes_intregs)(a0)
1010         ld     r9 ,( 9*8+offes_intregs)(a0)
1011         ld     r10,(10*8+offes_intregs)(a0)
1012         ld     r11,(11*8+offes_intregs)(a0)
1013         ld     r12,(12*8+offes_intregs)(a0)
1014         /* r13 is pv                      */
1015         ld     r14,(14*8+offes_intregs)(a0)
1016         ld     r15,(15*8+offes_intregs)(a0)
1017         ld     r16,(16*8+offes_intregs)(a0) /* link register */
1018         ld     r17,(17*8+offes_intregs)(a0)
1019         ld     r18,(18*8+offes_intregs)(a0)
1020         ld     r19,(19*8+offes_intregs)(a0)
1021         ld     r20,(20*8+offes_intregs)(a0)
1022         ld     r21,(21*8+offes_intregs)(a0)
1023         ld     r22,(22*8+offes_intregs)(a0)
1024         ld     r23,(23*8+offes_intregs)(a0)
1025         ld     r24,(24*8+offes_intregs)(a0)
1026         ld     r25,(25*8+offes_intregs)(a0)
1027         ld     r26,(26*8+offes_intregs)(a0)
1028         ld     r27,(27*8+offes_intregs)(a0)
1029         ld     r28,(28*8+offes_intregs)(a0)
1030         ld     r29,(29*8+offes_intregs)(a0)
1031         ld     r30,(30*8+offes_intregs)(a0)
1032         ld     r31,(31*8+offes_intregs)(a0)
1033         
1034         lfd     fr0 ,( 0*8+offes_fltregs)(a0)
1035         lfd     fr1 ,( 1*8+offes_fltregs)(a0)
1036         lfd     fr2 ,( 2*8+offes_fltregs)(a0)
1037         lfd     fr3 ,( 3*8+offes_fltregs)(a0)
1038         lfd     fr4 ,( 4*8+offes_fltregs)(a0)
1039         lfd     fr5 ,( 5*8+offes_fltregs)(a0)
1040         lfd     fr6 ,( 6*8+offes_fltregs)(a0)
1041         lfd     fr7 ,( 7*8+offes_fltregs)(a0)
1042         lfd     fr8 ,( 8*8+offes_fltregs)(a0)
1043         lfd     fr9 ,( 9*8+offes_fltregs)(a0)
1044         lfd     fr10,(10*8+offes_fltregs)(a0)
1045         lfd     fr11,(11*8+offes_fltregs)(a0)
1046         lfd     fr12,(12*8+offes_fltregs)(a0)
1047         lfd     fr13,(13*8+offes_fltregs)(a0)
1048         lfd     fr14,(14*8+offes_fltregs)(a0)
1049         lfd     fr15,(15*8+offes_fltregs)(a0)
1050         lfd     fr16,(16*8+offes_fltregs)(a0)
1051         lfd     fr17,(17*8+offes_fltregs)(a0)
1052         lfd     fr18,(18*8+offes_fltregs)(a0)
1053         lfd     fr19,(19*8+offes_fltregs)(a0)
1054         lfd     fr20,(20*8+offes_fltregs)(a0)
1055         lfd     fr21,(21*8+offes_fltregs)(a0)
1056         lfd     fr22,(22*8+offes_fltregs)(a0)
1057         lfd     fr23,(23*8+offes_fltregs)(a0)
1058         lfd     fr24,(24*8+offes_fltregs)(a0)
1059         lfd     fr25,(25*8+offes_fltregs)(a0)
1060         lfd     fr26,(26*8+offes_fltregs)(a0)
1061         lfd     fr27,(27*8+offes_fltregs)(a0)
1062         lfd     fr28,(28*8+offes_fltregs)(a0)
1063         lfd     fr29,(29*8+offes_fltregs)(a0)
1064         lfd     fr30,(30*8+offes_fltregs)(a0)
1065         lfd     fr31,(31*8+offes_fltregs)(a0)
1066
1067         /* restore link register */
1068
1069         mtlr    r16
1070         
1071         /* load new pc */
1072
1073         ld     itmp3,offes_pc(a0)
1074
1075         /* load a0 */
1076         
1077         ld     a0,(3*8+offes_intregs)(a0)
1078
1079         /* jump to new code */
1080
1081         mtctr   itmp3
1082         bctr
1083
1084 #endif /* defined(ENABLE_REPLACEMENT) */
1085
1086 /* asm_cacheflush **************************************************************
1087         copied from linux/arch/ppc64/kernel/vdso64/cacheflush.S
1088         assumes 128 byte cache line size.
1089         All registers used may be trashed for fun and profit.
1090 *******************************************************************************/
1091
1092         .section ".opd","aw"
1093         .align 3
1094 asm_cacheflush:
1095                 .quad   .asm_cacheflush,.TOC.@tocbase,0
1096                 .previous
1097                 .size asm_cacheflush, 24
1098                 .type .asm_cacheflush,@function
1099                 .globl .asm_cacheflush 
1100 .asm_cacheflush:
1101         /* construct the AND mask */
1102         li      r6,   0xffffffffffff8000
1103         ori     r6,r6,0x000000000000ff80
1104
1105         add     r4,r3,r4
1106         and.    r3,r3,r6
1107         addi    r4,r4,127
1108         and.    r4,r4,r6
1109         mr      r5,r3
1110 1:
1111         cmpld   r3,r4
1112         bge     0f
1113         dcbst   0,r3
1114         addi    r3,r3,128
1115         b       1b
1116 0:
1117         sync
1118 1:
1119         cmpld   r5,r4
1120         bge     0f
1121         icbi    0,r5
1122         addi    r5,r5,128
1123         b       1b
1124 0:
1125         sync
1126         isync
1127         blr
1128
1129 /*
1130                 asm_getclassvalues_atomic 
1131 */
1132         .section ".opd","aw"
1133         .align 3
1134 asm_getclassvalues_atomic:
1135                 .quad   .asm_getclassvalues_atomic,.TOC.@tocbase,0
1136                 .previous
1137                 .size asm_getclassvalues_atomic, 24
1138                 .type .asm_getclassvalues_atomic,@function
1139                 .globl .asm_getclassvalues_atomic
1140 .asm_getclassvalues_atomic:
1141
1142 _crit_restart:
1143 _crit_begin:
1144         lwz     r6,offbaseval(r3)
1145         lwz     r7,offdiffval(r3)
1146         lwz     r8,offbaseval(r4)
1147 _crit_end:
1148         stw     r6,offcast_super_baseval(r5)
1149         stw     r7,offcast_super_diffval(r5)
1150         stw     r8,offcast_sub_baseval(r5)
1151         blr
1152
1153         .data
1154
1155 asm_criticalsections:
1156 #if defined(ENABLE_THREADS)
1157         .quad   _crit_begin
1158         .quad   _crit_end
1159         .quad   _crit_restart
1160 #endif
1161         .quad 0
1162
1163 /* disable exec-stacks ********************************************************/
1164
1165 #if defined(__linux__) && defined(__ELF__)
1166         .section .note.GNU-stack,"",%progbits
1167 #endif
1168
1169
1170 /*
1171  * These are local overrides for various environment variables in Emacs.
1172  * Please do not remove this and leave it at the end of the file, where
1173  * Emacs will automagically detect them.
1174  * ---------------------------------------------------------------------
1175  * Local variables:
1176  * mode: asm
1177  * indent-tabs-mode: t
1178  * c-basic-offset: 4
1179  * tab-width: 4
1180  * End:
1181  * vim:noexpandtab:sw=4:ts=4:
1182  */