* src/vm/jit/powerpc64/linux/md-abi.h: New REG_TOC name needed to
[cacao.git] / src / vm / jit / powerpc64 / asmpart.S
1 /* src/vm/jit/powerpc64/asmpart.S - Java-C interface functions for PowerPC
2                 
3    Copyright (C) 1996-2005, 2006 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    Contact: cacao@cacaojvm.org
26
27    Authors: Andreas Krall
28             Reinhard Grafl
29             Stefan Ring
30
31    Changes: Christian Thalinger
32             Edwin Steiner
33
34    $Id: asmpart.S 5282 2006-08-28 19:31:37Z tbfg $
35
36 */
37
38
39 #include "config.h"
40
41 #include "md-abi.h"
42 #include "md-asm.h"
43
44 #include "vm/jit/abi-asm.h"
45 #include "vm/jit/methodheader.h"
46 #include "vm/jit/powerpc64/offsets.h"
47
48 .section ".toc","aw"
49 .section ".text"
50
51         .align 2        
52
53
54 /* export functions ***********************************************************/
55
56 #ifdef ENABLE_LIBJVM
57         .globl asm_vm_call_method
58         .globl asm_vm_call_method_int
59         .globl asm_vm_call_method_long
60         .globl asm_vm_call_method_float
61         .globl asm_vm_call_method_double
62 #else
63         .globl .asm_vm_call_method
64         .globl .asm_vm_call_method_int
65         .globl .asm_vm_call_method_long
66         .globl .asm_vm_call_method_float
67         .globl .asm_vm_call_method_double
68 #endif
69         .globl asm_vm_call_method_exception_handler
70
71         .globl asm_call_jit_compiler
72
73         .globl asm_handle_nat_exception
74         .globl asm_handle_exception
75
76         .globl asm_abstractmethoderror
77
78         .globl asm_patcher_wrapper
79
80         .globl asm_replacement_out
81         .globl .asm_replacement_in
82
83         .globl .asm_cacheflush          /* no function descriptor needed, only called direct */
84         .globl asm_criticalsections
85         .globl .asm_getclassvalues_atomic
86
87
88 /* asm_vm_call_method **********************************************************
89 *                                                                              *
90 *   This function calls a Java-method (which possibly needs compilation)       *
91 *   with up to 4 address parameters.                                           *
92 *                                                                              *
93 *   This functions calls the JIT-compiler which eventually translates the      *
94 *   method into machine code.                                                  *
95 *                                                                              *
96 *   C-prototype:                                                               *
97 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
98 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
99 *                                                                              *
100 *******************************************************************************/
101
102         .align 2
103
104         .long   0                         /* catch type all                       */
105         .long   0                         /* exception handler pc                 */
106         .long   0                         /* end pc                               */
107         .long   0                         /* start pc                             */
108         .long   1                         /* extable size                         */
109         .long   0                         /* line number table start              */
110         .long   0                         /* line number table size               */
111         .long   0                         /* fltsave                              */
112         .long   0                         /* intsave                              */
113         .long   0                         /* isleaf                               */
114         .long   0                         /* IsSync                               */
115         .long   0                         /* frame size                           */
116         .long   0                         /* codeinfo pointer                     */
117
118 #ifdef ENABLE_LIBJVM
119         .section ".opd","aw"
120         .align 3
121
122         asm_vm_call_method:
123         asm_vm_call_method_int:
124         asm_vm_call_method_long:
125         asm_vm_call_method_float:
126         asm_vm_call_method_double:
127                 .quad   .asm_vm_call_method,.TOC.@tocbase,0
128                 .previous
129                 .size asm_vm_call_method, 24
130                 .type .asm_vm_call_method,@function
131                 .globl .asm_vm_call_method
132 #else
133         asm_vm_call_method:
134         .globl asm_vm_call_method
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 #if defined(__DARWIN__)
150         std     itmp1,10*8(sp)            /* register r11 is callee saved         */
151 #endif
152         std     pv,11*8(sp)               /* save PV register                     */
153
154         std     itmp3,12*8(sp)            /* registers r14-r31 are callee saved   */
155         stfd    ftmp1,13*8(sp)            /* registers f14-f31 are callee saved   */
156         stfd    ftmp2,14*8(sp)
157
158 #if defined(__DARWIN__)
159         std     t1,15*8(r1)
160         std     t2,16*8(r1)
161         std     t3,17*8(r1)
162         std     t4,18*8(r1)
163         std     t5,19*8(r1)
164         std     t6,20*8(r1)
165         std     t7,21*8(r1)
166
167         stfd    ft0,22*8(r1)
168         stfd    ft1,23*8(r1)
169         stfd    ft2,24*8(r1)
170         stfd    ft3,25*8(r1)
171         stfd    ft4,26*8(r1)
172         stfd    ft5,27*8(r1)
173 #else
174         SAVE_TEMPORARY_REGISTERS(15)      /* the offset has to be even            */
175 #endif
176
177         mr      itmp2,a1                  /* arg count                            */
178         mr      itmp1,a2                  /* pointer to arg block                 */
179
180         mr      t4,itmp2                  /* save argument count                  */
181         mr      t5,itmp1                  /* save argument block pointer          */
182
183         mr      s0,sp                     /* save current sp to s0                */
184
185         addi    itmp1,itmp1,-sizevmarg    /* initialize pointer (smaller code)    */
186         addi    itmp2,itmp2,1             /* initialize argument count            */
187         li      t0,0                      /* initialize integer argument counter  */
188         li      t1,0                      /* initialize float argument counter    */
189         li      t6,0                      /* initialize integer register counter  */
190 #if defined(__DARWIN__)
191         li      t7,0                      /* initialize stack slot counter        */
192 #endif
193
194         mflr    r0                        /* save link register (PIC code)        */
195         bl      L_asm_vm_call_method_get_pc
196 L_asm_vm_call_method_get_pc:
197         mflr    t3                        /* t3 contains the current pc           */
198         mtlr    r0
199
200 L_register_copy:
201         addi    itmp1,itmp1,sizevmarg     /* goto next argument block             */
202         addi    itmp2,itmp2,-1            /* argument count - 1                   */
203         mr.     itmp2,itmp2
204         beq     L_register_copy_done
205
206         lwz     itmp3,offvmargtype+4(itmp1)
207         andi.   r0,itmp3,0x0002           /* is this a float/double type?         */
208         bne     L_register_handle_float
209         
210 L_register_handle_int:
211         cmpwi   t6,INT_ARG_CNT            /* are we out of integer argument       */
212         beq     L_register_copy           /* registers? yes, next loop            */
213
214         andi.   r0,itmp3,0x0001           /* is this a 2-word type?               */
215         bne     L_register_handle_long
216
217 #if defined(__DARWIN__)
218         addis   itmp3,t3,ha16(L_jumptable_int - L_asm_vm_call_method_get_pc)
219         la      itmp3,lo16(L_jumptable_int - L_asm_vm_call_method_get_pc)(itmp3)
220 #else
221         lis     itmp3,L_jumptable_int@highest           /* load 64bit address   */
222         ori     itmp3,itmp3,L_jumptable_int@higher
223         rldicr  itmp3,itmp3,32,31
224         oris    itmp3,itmp3,L_jumptable_int@h
225         ori     itmp3,itmp3,L_jumptable_int@l
226 #endif
227
228         slwi    t2,t6,2                   /* multiple of 4-bytes                  */
229         add     itmp3,itmp3,t2            /* calculate address of jumptable       */
230         ld     itmp3,0(itmp3)             /* load function address                */
231         mtctr   itmp3
232         addi    t0,t0,1                   /* integer argument counter             */
233         addi    t6,t6,1                   /* integer argument register counter    */
234 #if defined(__DARWIN__)
235         addi    t7,t7,1                   /* stack slot counter                   */
236 #endif
237         bctr
238
239 L_register_handle_long:
240 #if defined(__DARWIN__)
241         addis   itmp3,t3,ha16(L_jumptable_long - L_asm_vm_call_method_get_pc)
242         la      itmp3,lo16(L_jumptable_long - L_asm_vm_call_method_get_pc)(itmp3)
243 #else
244         lis     itmp3,L_jumptable_long@ha
245         addi    itmp3,itmp3,L_jumptable_long@l
246 #endif
247 #if !defined(__DARWIN__)
248         addi    t6,t6,1                   /* align to even numbers                */
249         andi.   t6,t6,0xfffe
250 #endif
251
252         cmpwi   t6,(INT_ARG_CNT - 1)      /* are we out of integer argument       */
253         blt     L_register_handle_long_continue /* registers?                     */
254
255         li      t6,INT_ARG_CNT            /* yes, set integer argument register   */
256         b       L_register_copy           /* count to max and next loop           */
257
258 L_register_handle_long_continue:
259         slwi    t2,t6,2                   /* multiple of 4-bytes                  */
260         add     itmp3,itmp3,t2            /* calculate address of jumptable       */
261         lwz     itmp3,0(itmp3)            /* load function address                */
262         mtctr   itmp3
263         addi    t0,t0,1                   /* integer argument counter             */
264         addi    t6,t6,2                   /* integer argument register counter    */
265 #if defined(__DARWIN__)
266         addi    t7,t7,2                   /* stack slot counter                   */
267 #endif
268         bctr
269
270 L_register_handle_float:
271         cmpwi   t1,FLT_ARG_CNT            /* are we out of float argument         */
272         beq     L_register_copy           /* registers? yes, next loop            */
273
274         andi.   r0,itmp3,0x0001           /* is this a 2-word type?               */
275         bne     L_register_handle_double
276
277 #if defined(__DARWIN__)
278         addis   itmp3,t3,ha16(L_jumptable_float - L_asm_vm_call_method_get_pc)
279         la      itmp3,lo16(L_jumptable_float - L_asm_vm_call_method_get_pc)(itmp3)
280 #else
281         lis     itmp3,L_jumptable_float@ha
282         addi    itmp3,itmp3,L_jumptable_float@l
283 #endif
284
285         slwi    t2,t1,2                   /* multiple of 4-bytes                  */
286         add     itmp3,itmp3,t2            /* calculate address of jumptable       */
287         lwz     itmp3,0(itmp3)            /* load function address                */
288         mtctr   itmp3
289         addi    t1,t1,1                   /* float argument counter               */
290 #if defined(__DARWIN__)
291         addi    t7,t7,1                   /* stack slot counter                   */
292         addi    t6,t6,1                   /* skip 1 integer argument register     */
293 #endif
294         bctr
295
296 L_register_handle_double:
297 #if defined(__DARWIN__)
298         addis   itmp3,t3,ha16(L_jumptable_double - L_asm_vm_call_method_get_pc)
299         la      itmp3,lo16(L_jumptable_double - L_asm_vm_call_method_get_pc)(itmp3)
300 #else
301         lis     itmp3,L_jumptable_double@ha
302         addi    itmp3,itmp3,L_jumptable_double@l
303 #endif
304
305         slwi    t2,t1,2                   /* multiple of 4-bytes                  */
306         add     itmp3,itmp3,t2            /* calculate address of jumptable       */
307         lwz     itmp3,0(itmp3)            /* load function address                */
308         mtctr   itmp3
309         addi    t1,t1,1                   /* float argument counter               */
310 #if defined(__DARWIN__)
311         addi    t7,t7,2                   /* stack slot counter                   */
312         addi    t6,t6,2                   /* skip 2 integer argument registers    */
313 #endif
314         bctr
315
316 L_register_copy_done:
317                                           /* calculate remaining arguments        */
318         sub     itmp3,t4,t0               /* - integer arguments in registers     */
319         sub     itmp3,itmp3,t1            /* - float arguments in registers       */
320         mr.     itmp3,itmp3
321         beq     L_stack_copy_done
322
323         mr      itmp2,t4                  /* restore argument count               */
324         mr      itmp1,t5                  /* restore argument block pointer       */
325
326         slwi    t4,itmp3,3                /* XXX use 8-bytes slots for now        */
327         addi    t4,t4,LA_SIZE             /* add size of linkage area             */
328
329 #if defined(__DARWIN__)
330         slwi    t5,t7,2                   /* add stack space for arguments        */
331         add     t4,t4,t5
332 #endif
333
334         sub     sp,sp,t4
335
336         mr      t6,sp                     /* use t6 as temporary sp               */
337         addi    t6,t6,LA_SIZE             /* skip linkage area                    */
338 #if defined(__DARWIN__)
339         add     t6,t6,t5                  /* skip stack space for arguments       */
340 #endif
341
342         addi    itmp1,itmp1,-sizevmarg    /* initialize pointer (smaller code)    */
343         addi    itmp2,itmp2,1             /* initialize argument count            */
344         
345 L_stack_copy_loop:
346         addi    itmp1,itmp1,sizevmarg     /* goto next argument block             */
347         addi    itmp2,itmp2,-1            /* argument count - 1                   */
348         mr.     itmp2,itmp2
349         beq     L_stack_copy_done
350         
351         lwz     itmp3,offvmargtype+4(itmp1)
352         andi.   r0,itmp3,0x0002           /* is this a float/double type?         */
353         bne     L_stack_handle_float
354
355 L_stack_handle_int:
356         addi    t0,t0,-1                  /* arguments assigned to registers      */
357         mr.     t0,t0
358         bge     L_stack_copy_loop
359
360         andi.   r0,itmp3,0x0001           /* is this a 2-word type?               */
361         bne     L_stack_handle_long
362
363         lwz     itmp3,offvmargdata+4(itmp1) /* get integer argument               */
364         stw     itmp3,0(t6)               /* and store it on the stack            */
365         addi    t6,t6,4                   /* increase temporary sp by 1 slot      */
366         b       L_stack_copy_loop
367
368 L_stack_handle_long:
369 #if !defined(__DARWIN__)
370         addi    t6,t6,4                   /* align stack to 8-bytes               */
371         rlwinm  t6,t6,0,30,28             /* clear lower 4-bits                   */
372 #endif
373
374         lwz     itmp3,offvmargdata+0(itmp1) /* get long argument                  */
375         stw     itmp3,0(t6)               /* and store it on the stack            */
376         lwz     itmp3,offvmargdata+4(itmp1)
377         stw     itmp3,4(t6)
378         addi    t6,t6,8                   /* increase temporary sp by 2 slots     */
379         b       L_stack_copy_loop
380                 
381 L_stack_handle_float:
382         addi    t1,t1,-1                  /* arguments assigned to registers      */
383         mr.     t1,t1
384         bge     L_stack_copy_loop
385
386         andi.   r0,itmp3,0x0001           /* is this a 2-word type?               */
387         bne     L_stack_handle_double
388
389         lfs     ftmp3,offvmargdata(itmp1) /* get float argument                   */
390         stfs    ftmp3,0(t6)               /* and store it on the stack            */
391         addi    t6,t6,4                   /* increase temporary sp by 1 slot      */
392         b       L_stack_copy_loop
393
394 L_stack_handle_double:
395 #if !defined(__DARWIN__)
396         addi    t6,t6,4                   /* align stack to 8-bytes               */
397         rlwinm  t6,t6,0,30,28             /* clear lower 4-bits                   */
398 #endif
399
400         lfd     ftmp3,offvmargdata(itmp1) /* get double argument                  */
401         stfd    ftmp3,0(t6)               /* and store it on the stack            */
402         addi    t6,t6,8                   /* increase temporary sp by 2 slots     */
403         b       L_stack_copy_loop
404
405 L_stack_copy_done:
406         ld      itmp1,9*8(s0)             /* pass method pointer via tmp1         */
407
408 #if defined(__DARWIN__)
409         addis   mptr,t3,ha16(L_asm_call_jit_compiler - L_asm_vm_call_method_get_pc)
410         la      mptr,lo16(L_asm_call_jit_compiler - L_asm_vm_call_method_get_pc)(mptr)
411 #else
412         lis     mptr,L_asm_call_jit_compiler@highest    /* load 64bit address   */
413         ori     mptr,mptr,L_asm_call_jit_compiler@higher
414         rldicr  mptr,mptr,32,31
415         oris    mptr,mptr,L_asm_call_jit_compiler@h
416         ori     mptr,mptr,L_asm_call_jit_compiler@l
417 #endif
418         std     mptr,7*8(s0)
419         addi    mptr,s0,7*8
420
421         ld      pv,0*8(mptr)
422         mtctr   pv
423         bctrl
424 1:
425         mflr    itmp1
426 #if defined(__DARWIN__)
427         addi    pv,itmp1,lo16(.asm_vm_call_method - 1b)
428 #else
429         addi    pv,itmp1,(.asm_vm_call_method - 1b)@l
430 #endif
431
432 L_asm_vm_call_method_return:
433         mr      sp,s0                     /* restore the function's sp            */
434
435         ld      s0,8*8(sp)                /* restore used callee saved registers  */
436
437 #if defined(__DARWIN__)
438         lwz     itmp1,10*4(sp)            /* register r11 is callee saved         */
439 #endif
440         ld      pv,11*8(sp)               /* save PV register                     */
441
442         ld      itmp3,12*8(sp)
443         lfd     ftmp1,14*8(sp)            /* registers f14-f31 are callee saved   */
444         lfd     ftmp2,16*8(sp)
445
446 #if defined(__DARWIN__)
447         lwz     t1,18*4(r1)
448         lwz     t2,19*4(r1)
449         lwz     t3,20*4(r1)
450         lwz     t4,21*4(r1)
451         lwz     t5,22*4(r1)
452         lwz     t6,23*4(r1)
453         lwz     t7,24*4(r1)
454
455         lfd     ft0,26*4(r1)
456         lfd     ft1,28*4(r1)
457         lfd     ft2,30*4(r1)
458         lfd     ft3,32*4(r1)
459         lfd     ft4,34*4(r1)
460         lfd     ft5,36*4(r1)
461 #else
462         RESTORE_TEMPORARY_REGISTERS(18)   /* the offset has to be even            */
463 #endif
464
465         ld     r0,40*8+LA_LR_OFFSET(r1)
466         mtlr    r0
467         addi    r1,r1,40*8
468         blr
469
470 asm_vm_call_method_exception_handler:
471         mr      r3,itmp1
472         bl      builtin_throw_exception
473         b       L_asm_vm_call_method_return
474
475
476         .data
477         .align  4
478
479 L_jumptable_int:
480         .quad   L_handle_a0
481         .quad   L_handle_a1
482         .quad   L_handle_a2
483         .quad   L_handle_a3
484         .quad   L_handle_a4
485         .quad   L_handle_a5
486         .quad   L_handle_a6
487         .quad   L_handle_a7
488
489         .text
490         .align  4
491
492 L_handle_a0:
493         lwz     a0,offvmargdata+4(itmp1)
494         b       L_register_copy
495 L_handle_a1:
496         lwz     a1,offvmargdata+4(itmp1)
497         b       L_register_copy
498 L_handle_a2:
499         lwz     a2,offvmargdata+4(itmp1)
500         b       L_register_copy
501 L_handle_a3:
502         lwz     a3,offvmargdata+4(itmp1)
503         b       L_register_copy
504 L_handle_a4:
505         lwz     a4,offvmargdata+4(itmp1)
506         b       L_register_copy
507 L_handle_a5:
508         lwz     a5,offvmargdata+4(itmp1)
509         b       L_register_copy
510 L_handle_a6:
511         lwz     a6,offvmargdata+4(itmp1)
512         b       L_register_copy
513 L_handle_a7:
514         lwz     a7,offvmargdata+4(itmp1)
515         b       L_register_copy
516
517
518         .data
519         .align  2
520
521 L_jumptable_long:
522 #if defined(__DARWIN__)
523         .quad   L_handle_a0_a1
524         .quad   L_handle_a1_a2
525         .quad   L_handle_a2_a3
526         .quad   L_handle_a3_a4
527         .quad   L_handle_a4_a5
528         .quad   L_handle_a5_a6
529         .quad   L_handle_a6_a7
530 #else
531         /* we have two entries here, so we get the even argument register
532         alignment for linux */
533
534         .quad   L_handle_a0_a1
535         .quad   0
536         .quad   L_handle_a2_a3
537         .quad   0
538         .quad   L_handle_a4_a5
539         .quad   0
540         .quad   L_handle_a6_a7
541 #endif
542
543         .text
544         .align  2
545
546 L_handle_a0_a1:
547         lwz     a0,offvmargdata+0(itmp1)
548         lwz     a1,offvmargdata+4(itmp1)
549         b       L_register_copy
550 #if defined(__DARWIN__)
551 L_handle_a1_a2:
552         lwz     a1,offvmargdata+0(itmp1)
553         lwz     a2,offvmargdata+4(itmp1)
554         b       L_register_copy
555 #endif
556 L_handle_a2_a3:
557         lwz     a2,offvmargdata+0(itmp1)
558         lwz     a3,offvmargdata+4(itmp1)
559         b       L_register_copy
560 #if defined(__DARWIN__)
561 L_handle_a3_a4:
562         lwz     a3,offvmargdata+0(itmp1)
563         lwz     a4,offvmargdata+4(itmp1)
564         b       L_register_copy
565 #endif
566 L_handle_a4_a5:
567         lwz     a4,offvmargdata+0(itmp1)
568         lwz     a5,offvmargdata+4(itmp1)
569         b       L_register_copy
570 #if defined(__DARWIN__)
571 L_handle_a5_a6:
572         lwz     a5,offvmargdata+0(itmp1)
573         lwz     a6,offvmargdata+4(itmp1)
574         b       L_register_copy
575 #endif
576 L_handle_a6_a7:
577         lwz     a6,offvmargdata+0(itmp1)
578         lwz     a7,offvmargdata+4(itmp1)
579         b       L_register_copy
580
581
582         .data
583         .align  2
584
585 L_jumptable_float:
586         .quad   L_handle_fa0
587         .quad   L_handle_fa1
588         .quad   L_handle_fa2
589         .quad   L_handle_fa3
590         .quad   L_handle_fa4
591         .quad   L_handle_fa5
592         .quad   L_handle_fa6
593         .quad   L_handle_fa7
594
595 #if defined(__DARWIN__)
596         .quad   L_handle_fa8
597         .quad   L_handle_fa9
598         .quad   L_handle_fa10
599         .quad   L_handle_fa11
600         .quad   L_handle_fa12
601 #endif
602
603         .text
604         .align  2
605
606 L_handle_fa0:
607         lfs     fa0,offvmargdata(itmp1)
608         b       L_register_copy
609 L_handle_fa1:
610         lfs     fa1,offvmargdata(itmp1)
611         b       L_register_copy
612 L_handle_fa2:
613         lfs     fa2,offvmargdata(itmp1)
614         b       L_register_copy
615 L_handle_fa3:
616         lfs     fa3,offvmargdata(itmp1)
617         b       L_register_copy
618 L_handle_fa4:
619         lfs     fa4,offvmargdata(itmp1)
620         b       L_register_copy
621 L_handle_fa5:
622         lfs     fa5,offvmargdata(itmp1)
623         b       L_register_copy
624 L_handle_fa6:
625         lfs     fa6,offvmargdata(itmp1)
626         b       L_register_copy
627 L_handle_fa7:
628         lfs     fa7,offvmargdata(itmp1)
629         b       L_register_copy
630
631 #if defined(__DARWIN__)
632 L_handle_fa8:
633         lfs     fa8,offvmargdata(itmp1)
634         b       L_register_copy
635 L_handle_fa9:
636         lfs     fa9,offvmargdata(itmp1)
637         b       L_register_copy
638 L_handle_fa10:
639         lfs     fa10,offvmargdata(itmp1)
640         b       L_register_copy
641 L_handle_fa11:
642         lfs     fa11,offvmargdata(itmp1)
643         b       L_register_copy
644 L_handle_fa12:
645         lfs     fa12,offvmargdata(itmp1)
646         b       L_register_copy
647 #endif
648
649
650         .data
651         .align  2
652
653 L_jumptable_double:
654         .quad   L_handle_fda0
655         .quad   L_handle_fda1
656         .quad   L_handle_fda2
657         .quad   L_handle_fda3
658         .quad   L_handle_fda4
659         .quad   L_handle_fda5
660         .quad   L_handle_fda6
661         .quad   L_handle_fda7
662
663 #if defined(__DARWIN__)
664         .quad   L_handle_fda8
665         .quad   L_handle_fda9
666         .quad   L_handle_fda10
667         .quad   L_handle_fda11
668         .quad   L_handle_fda12
669 #endif
670
671         .text
672         .align  2
673
674 L_handle_fda0:
675         lfd     fa0,offvmargdata(itmp1)
676         b       L_register_copy
677 L_handle_fda1:
678         lfd     fa1,offvmargdata(itmp1)
679         b       L_register_copy
680 L_handle_fda2:
681         lfd     fa2,offvmargdata(itmp1)
682         b       L_register_copy
683 L_handle_fda3:
684         lfd     fa3,offvmargdata(itmp1)
685         b       L_register_copy
686 L_handle_fda4:
687         lfd     fa4,offvmargdata(itmp1)
688         b       L_register_copy
689 L_handle_fda5:
690         lfd     fa5,offvmargdata(itmp1)
691         b       L_register_copy
692 L_handle_fda6:
693         lfd     fa6,offvmargdata(itmp1)
694         b       L_register_copy
695 L_handle_fda7:
696         lfd     fa7,offvmargdata(itmp1)
697         b       L_register_copy
698
699 #if defined(__DARWIN__)
700 L_handle_fda8:
701         lfd     fa8,offvmargdata(itmp1)
702         b       L_register_copy
703 L_handle_fda9:
704         lfd     fa9,offvmargdata(itmp1)
705         b       L_register_copy
706 L_handle_fda10:
707         lfd     fa10,offvmargdata(itmp1)
708         b       L_register_copy
709 L_handle_fda11:
710         lfd     fa11,offvmargdata(itmp1)
711         b       L_register_copy
712 L_handle_fda12:
713         lfd     fa12,offvmargdata(itmp1)
714         b       L_register_copy
715 #endif
716
717
718 /* asm_call_jit_compiler *******************************************************
719
720    Invokes the compiler for untranslated JavaVM methods.
721
722 *******************************************************************************/
723
724 asm_call_jit_compiler:
725 L_asm_call_jit_compiler:                /* required for PIC code              */
726         mflr    r0
727         std     r0,LA_LR_OFFSET(sp)         /* save return address                */
728         stdu    r1,-(LA_SIZE+PA_SIZE+ARG_CNT*8)(sp)
729
730 #if defined(__DARWIN__)
731         stw     a0,LA_SIZE+(5+0)*8(r1)
732         stw     a1,LA_SIZE+(5+1)*8(r1)
733         stw     a2,LA_SIZE+(5+2)*8(r1)
734         stw     a3,LA_SIZE+(5+3)*8(r1)
735         stw     a4,LA_SIZE+(5+4)*8(r1)
736         stw     a5,LA_SIZE+(5+5)*8(r1)
737         stw     a6,LA_SIZE+(5+6)*8(r1)
738         stw     a7,LA_SIZE+(5+7)*8(r1)
739
740         stfd    fa0,LA_SIZE+(5+8)*8(r1)
741         stfd    fa1,LA_SIZE+(5+10)*8(r1)
742         stfd    fa2,LA_SIZE+(5+12)*8(r1)
743         stfd    fa3,LA_SIZE+(5+14)*8(r1)
744         stfd    fa4,LA_SIZE+(5+16)*8(r1)
745         stfd    fa5,LA_SIZE+(5+18)*8(r1)
746         stfd    fa6,LA_SIZE+(5+20)*8(r1)
747         stfd    fa7,LA_SIZE+(5+22)*8(r1)
748         stfd    fa8,LA_SIZE+(5+24)*8(r1)
749         stfd    fa9,LA_SIZE+(5+26)*8(r1)
750         stfd    fa10,LA_SIZE+(5+28)*8(r1)
751         stfd    fa11,LA_SIZE+(5+30)*8(r1)
752         stfd    fa12,LA_SIZE+(5+32)*8(r1)
753 #else
754         SAVE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS)
755 #endif
756
757         mr      a0,itmp1
758         mr      a1,mptr
759         addi    a2,sp,(LA_SIZE + PA_SIZE+ ARG_CNT*8)
760         ld      a3,(LA_SIZE + PA_SIZE + ARG_CNT*8)+LA_LR_OFFSET(sp)
761         bl      jit_asm_compile
762         ori     r0,r0,0                     /* nop needed after jump to function desc. */
763         mr      pv,v0                       /* move address to pv register        */
764
765 #if defined(__DARWIN__)
766         lwz     a0,LA_SIZE+(+5+0)*8(r1)
767         lwz     a1,LA_SIZE+(+5+1)*8(r1)
768         lwz     a2,LA_SIZE+(+5+2)*8(r1)
769         lwz     a3,LA_SIZE+(+5+3)*8(r1)
770         lwz     a4,LA_SIZE+(+5+4)*8(r1)
771         lwz     a5,LA_SIZE+(+5+5)*8(r1)
772         lwz     a6,LA_SIZE+(+5+6)*8(r1)
773         lwz     a7,LA_SIZE+(+5+7)*8(r1)
774
775         lfd     fa0,LA_SIZE+(+5+8)*8(r1)
776         lfd     fa1,LA_SIZE+(+5+10)*8(r1)
777         lfd     fa2,LA_SIZE+(+5+12)*8(r1)
778         lfd     fa3,LA_SIZE+(+5+14)*8(r1)
779         lfd     fa4,LA_SIZE+(+5+16)*8(r1)
780         lfd     fa5,LA_SIZE+(+5+18)*8(r1)
781         lfd     fa6,LA_SIZE+(+5+20)*8(r1)
782         lfd     fa7,LA_SIZE+(+5+22)*8(r1)
783         lfd     fa8,LA_SIZE+(+5+24)*8(r1)
784         lfd     fa9,LA_SIZE+(+5+26)*8(r1)
785         lfd     fa10,LA_SIZE+(+5+28)*8(r1)
786         lfd     fa11,LA_SIZE+(+5+30)*8(r1)
787         lfd     fa12,LA_SIZE+(+5+32)*8(r1)
788 #else
789         RESTORE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS)
790 #endif
791
792         ld     itmp1,(LA_SIZE + PA_SIZE + ARG_CNT*8)+LA_LR_OFFSET(sp)
793         mtlr   itmp1
794
795         addi    sp,sp,(LA_SIZE + PA_SIZE + ARG_CNT*8)
796
797         mr.     pv,pv                       /* test for exception                 */
798         beq     L_asm_call_jit_compiler_exception
799
800         mtctr   pv                          /* move method address to control reg */
801         bctr                                /* and call the Java method           */
802
803 L_asm_call_jit_compiler_exception:
804         mflr    r0
805         stw     r0,LA_LR_OFFSET(sp)
806         stwu    sp,-LA_SIZE_ALIGNED(sp)     /* preserve linkage area              */
807         bl      exceptions_get_and_clear_exception
808         lwz     xpc,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
809         mtlr    xpc     
810         addi    sp,sp,LA_SIZE_ALIGNED
811
812         mr      xptr,v0                     /* get exception                      */
813         addi    xpc,xpc,-4                  /* exception address is ra - 4        */
814         b       L_asm_handle_nat_exception
815
816
817 /********************* function asm_handle_exception ***************************
818 *                                                                              *
819 *   This function handles an exception. It does not use the usual calling      *
820 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
821 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
822 *   the local exception table for a handler. If no one is found, it unwinds    *
823 *   stacks and continues searching the callers.                                *
824 *                                                                              *
825 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
826 *                                                                              *
827 *******************************************************************************/
828                 
829 asm_handle_nat_exception:
830 L_asm_handle_nat_exception:             /* required for PIC code              */
831         mflr    r9
832         lwz     itmp3,4(r9)
833         extsh   itmp3,itmp3
834         add     pv,itmp3,r9
835         lwz     itmp3,8(r9)
836         srwi    itmp3,itmp3,16
837         cmpwi   itmp3,0x3dad
838         bne     L_asm_handle_exception
839         lwz     itmp3,8(r9)
840         slwi    itmp3,itmp3,16
841         add     pv,pv,itmp3
842
843 asm_handle_exception:
844 L_asm_handle_exception:                 /* required for PIC code              */
845         addi    sp,sp,-(ARG_CNT+TMP_CNT)*8  /* create maybe-leaf stackframe       */
846
847 #if defined(__DARWIN__)
848 #else
849         SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
850         SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
851 #endif
852
853         li      a3,(ARG_CNT+TMP_CNT)*8      /* prepare a3 for handle_exception    */
854         li      a4,1                        /* set maybe-leaf flag                */
855
856 L_asm_handle_exception_stack_loop:
857         addi    sp,sp,-(LA_SIZE+PA_SIZE+4*8) /* allocate stack                     */
858         std     xptr,LA_SIZE+PA_SIZE+1*8(sp)        /* save exception pointer             */
859         std     pv,LA_SIZE+PA_SIZE+2*8(sp)          /* save data segment pointer          */
860         mflr    r0                                  /* save return address                */
861         std     r0,LA_SIZE+PA_SIZE+3*8(sp)              /* XXX */
862         add     a3,a3,sp                    /* calculate Java sp into a3...       */
863         addi    a3,a3,LA_SIZE+PA_SIZE+4*8
864         std     a4,LA_SIZE+PA_SIZE+4*8(sp)          /* save maybe-leaf flag               */
865
866         mr      a0,xptr                     /* pass exception pointer             */
867         mr      a1,xpc                      /* pass exception pc                  */
868         mr      a2,pv                       /* pass data segment pointer          */
869                                             /* a3 is still set                    */
870         bl      exceptions_handle_exception
871
872         mr.     v0,v0
873         beq     L_asm_handle_exception_not_catched
874
875         mr      xpc,v0                      /* move handlerpc into xpc            */
876         ld      xptr,LA_SIZE+PA_SIZE+1*8(sp)        /* restore exception pointer          */
877         ld      pv,LA_SIZE+PA_SIZE+2*8(sp)          /* restore data segment pointer       */
878         ld      r0,LA_SIZE+PA_SIZE+3*8(sp)          /* restore return address             */
879         mtlr    r0
880         ld      a4,LA_SIZE+PA_SIZE+4*8(sp)          /* get maybe-leaf flag                */
881         addi    sp,sp,LA_SIZE+PA_SIZE+4*8  /* free stack frame                   */
882
883         mr.     a4,a4
884         beq     L_asm_handle_exception_no_leaf
885
886 #if defined(__DARWIN__)
887 #else
888         RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
889         RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
890 #endif
891
892         addi    sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
893
894 L_asm_handle_exception_no_leaf:
895         mtctr   xpc                         /* jump to the handler                */
896         bctr
897
898 L_asm_handle_exception_not_catched:
899         ld      xptr,LA_SIZE+PA_SIZE+1*8(sp)        /* restore exception pointer          */
900         ld      pv,LA_SIZE+PA_SIZE+2*8(sp)          /* restore data segment pointer       */
901         ld      r0,LA_SIZE+PA_SIZE+3*8(sp)          /* restore return address             */
902         mtlr    r0
903         ld      a4,LA_SIZE+PA_SIZE+4*8(sp)          /* get maybe-leaf flag                */
904         addi    sp,sp,LA_SIZE+PA_SIZE+4*8  /* free stack frame                   */
905
906         mr.     a4,a4
907         beq     L_asm_handle_exception_no_leaf_stack
908
909         addi    sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
910         li      a4,0                        /* clear the maybe-leaf flag          */
911
912 L_asm_handle_exception_no_leaf_stack:
913         ld      t0,FrameSize(pv)            /* get frame size                     */
914         add     t0,sp,t0                    /* pointer to save area               */
915
916         ld      t1,IsLeaf(pv)               /* is leaf procedure                  */
917         mr.     t1,t1
918         bne     L_asm_handle_exception_no_ra_restore
919
920         ld      r0,LA_LR_OFFSET(t0)         /* restore ra                         */
921         mtlr    r0
922
923 L_asm_handle_exception_no_ra_restore:
924         mflr    xpc                         /* the new xpc is ra                  */
925         ld      t1,IntSave(pv)              /* t1 = saved int register count      */
926         bl      ex_int1
927 ex_int1:
928         mflr    t2                          /* t2 = current pc                    */
929 #if defined(__DARWIN__)
930         addi    t2,t2,lo16(ex_int2-ex_int1)
931 #else
932         addi    t2,t2,(ex_int2-ex_int1)@l
933 #endif
934         slwi    t1,t1,3                     /* t1 = register count * 8            */
935         subf    t2,t1,t2                    /* t2 = IntSave - t1                  */
936         mtctr   t2
937         bctr
938
939         ld      s0,-10*8(t0)
940         ld      s1,-9*8(t0)
941         ld      s2,-8*8(t0)
942         ld      s3,-7*8(t0)
943         ld      s4,-6*8(t0)
944         ld      s5,-5*8(t0)
945         ld      s6,-4*8(t0)
946         ld      s7,-3*8(t0)
947         ld      s8,-2*8(t0)
948         /*lwz     s9,-1*4(t0) XXX */
949
950 ex_int2:
951         subf    t0,t1,t0                    /* t0 = t0 - register count * 8       */
952
953         ld      t1,FltSave(pv)
954         bl      ex_flt1
955 ex_flt1:
956         mflr    t2
957 #if defined(__DARWIN__)
958         addi    t2,t2,lo16(ex_flt2-ex_flt1)
959 #else
960         addi    t2,t2,(ex_flt2-ex_flt1)@l
961 #endif
962         slwi    t1,t1,3                     /* t1 = register count * 8            */
963         subf    t2,t1,t2                    /* t2 = FltSave - t1                  */
964         mtctr   t2
965         bctr
966
967         lfd     fs0,-10*8(t0)
968         lfd     fs1,-9*8(t0)
969         lfd     fs2,-8*8(t0)
970         lfd     fs3,-7*8(t0)
971         lfd     fs4,-6*8(t0)
972         lfd     fs5,-5*8(t0)
973         lfd     fs6,-4*8(t0)
974         lfd     fs7,-3*8(t0)
975         lfd     fs8,-2*8(t0)
976         lfd     fs9,-1*8(t0)
977
978 ex_flt2:
979         ld      t0,FrameSize(pv)            /* get frame size                     */
980         add     sp,sp,t0                    /* unwind stack                       */
981         li      a3,0                        /* prepare a3 for handle_exception    */
982
983         mtlr    xpc
984         ld      itmp3,8(xpc)
985         extsh   itmp3,itmp3
986         add     pv,itmp3,xpc
987         ld      itmp3,16(xpc)
988         srwi    itmp3,itmp3,16
989         cmpwi   itmp3,0x3dad
990         bne     L_asm_handle_exception_stack_loop
991         ld      itmp3,16(xpc)
992         slwi    itmp3,itmp3,16
993         add     pv,pv,itmp3
994
995         b       L_asm_handle_exception_stack_loop
996
997
998 /* asm_abstractmethoderror *****************************************************
999
1000    Creates and throws an AbstractMethodError.
1001
1002 *******************************************************************************/
1003
1004 asm_abstractmethoderror:
1005         mflr    r0
1006         stw     r0,LA_LR_OFFSET(sp)
1007         stwu    sp,-LA_SIZE_ALIGNED(sp)     /* preserve linkage area              */
1008         addi    a0,sp,LA_SIZE_ALIGNED       /* pass java sp                       */
1009         mr      a1,r0                       /* pass exception address             */
1010         bl      exceptions_asm_new_abstractmethoderror
1011         lwz     r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
1012         mtlr    r0                          /* restore return address             */
1013         addi    sp,sp,LA_SIZE_ALIGNED
1014
1015         mr      xptr,v0                     /* get exception pointer              */
1016         mr      xpc,r0                      /* we can't use r0 directly in addi   */
1017         addi    xpc,xpc,-4                  /* exception address is ra - 4        */
1018         b       L_asm_handle_nat_exception
1019
1020
1021 /* asm_patcher_wrapper *********************************************************
1022
1023    XXX
1024
1025    Stack layout:
1026      40   return address into JIT code (patch position)
1027      32   pointer to virtual java_objectheader
1028      24   machine code (which is patched back later)
1029      16   unresolved class/method/field reference
1030       8   data segment displacement from load instructions
1031       0   patcher function pointer to call (pv is saved here afterwards)
1032
1033 *******************************************************************************/
1034
1035 asm_patcher_wrapper:
1036         mflr    r0                    /* get Java return address (leaf)           */
1037         std     r0,6*8(sp)            /* store it in the stub stackframe          */
1038                                       /* keep stack 16-bytes aligned: 6+1+37 = 44 */
1039         stdu    sp,-(LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8)(sp)
1040
1041 #if defined(__DARWIN__)
1042         stw     a0,LA_SIZE+(5+0)*8(r1)      /* save argument registers            */
1043         stw     a1,LA_SIZE+(5+1)*8(r1)      /* preserve linkage area (24 bytes)   */
1044         stw     a2,LA_SIZE+(5+2)*8(r1)      /* and 4 bytes for 4 argument         */
1045         stw     a3,LA_SIZE+(5+3)*8(r1)
1046         stw     a4,LA_SIZE+(5+4)*8(r1)
1047         stw     a5,LA_SIZE+(5+5)*8(r1)
1048         stw     a6,LA_SIZE+(5+6)*8(r1)
1049         stw     a7,LA_SIZE+(5+7)*8(r1)
1050
1051         stfd    fa0,LA_SIZE+(5+8)*8(sp)
1052         stfd    fa1,LA_SIZE+(5+10)*8(sp)
1053         stfd    fa2,LA_SIZE+(5+12)*8(sp)
1054         stfd    fa3,LA_SIZE+(5+14)*8(sp)
1055         stfd    fa4,LA_SIZE+(5+16)*8(sp)
1056         stfd    fa5,LA_SIZE+(5+18)*8(sp)
1057         stfd    fa6,LA_SIZE+(5+20)*8(sp)
1058         stfd    fa7,LA_SIZE+(5+22)*8(sp)
1059         stfd    fa8,LA_SIZE+(5+24)*8(sp)
1060         stfd    fa9,LA_SIZE+(5+26)*8(sp)
1061         stfd    fa10,LA_SIZE+(5+28)*8(sp)
1062         stfd    fa11,LA_SIZE+(5+30)*8(sp)
1063         stfd    fa12,LA_SIZE+(5+32)*8(sp)       /* XXX */
1064
1065         stw     t0,LA_SIZE+(+5+33)*8(r1)
1066         stw     t1,LA_SIZE+(+5+34)*8(r1)
1067         stw     t2,LA_SIZE+(+5+35)*8(r1)
1068         stw     t3,LA_SIZE+(+5+36)*8(r1)
1069         stw     t4,LA_SIZE+(+5+37)*8(r1)
1070         stw     t5,LA_SIZE+(+5+38)*8(r1)
1071         stw     t6,LA_SIZE+(+5+39)*8(r1)
1072         stw     t7,LA_SIZE+(+5+40)*8(r1)
1073
1074         stfd    ft0,LA_SIZE+(+5+42)*8(r1)
1075         stfd    ft1,LA_SIZE+(+5+44)*8(r1)
1076         stfd    ft2,LA_SIZE+(+5+46)*8(r1)
1077         stfd    ft3,LA_SIZE+(+5+48)*8(r1)
1078         stfd    ft4,LA_SIZE+(+5+50)*8(r1)
1079         stfd    ft5,LA_SIZE+(+5+52)*8(r1)
1080 #else
1081         SAVE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS) /* save 8 int/8 float arguments   */
1082         SAVE_TEMPORARY_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS+ARG_CNT)
1083 #endif
1084
1085         std     itmp1,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+1*8(sp)
1086         std     itmp2,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+2*8(sp)
1087         std     pv,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+3*8(sp)
1088
1089         addi    a0,sp,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8      /* pass SP of patcher stub            */
1090         mr      a1,pv                       /* pass PV                            */
1091         mr      a2,r0                       /* pass RA (correct for leafs)        */
1092         bl      patcher_wrapper
1093         std     v0,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+4*8(sp)     /* save return value                  */
1094
1095 #if defined(__DARWIN__)
1096         lwz     a0,LA_SIZE+(5+0)*8(r1)
1097         lwz     a1,LA_SIZE+(5+1)*8(r1)
1098         lwz     a2,LA_SIZE+(5+2)*8(r1)
1099         lwz     a3,LA_SIZE+(5+3)*8(r1)
1100         lwz     a4,LA_SIZE+(5+4)*8(r1)
1101         lwz     a5,LA_SIZE+(5+5)*8(r1)
1102         lwz     a6,LA_SIZE+(5+6)*8(r1)
1103         lwz     a7,LA_SIZE+(5+7)*8(r1)
1104
1105         lfd     fa0,LA_SIZE+(5+8)*8(sp)
1106         lfd     fa1,LA_SIZE+(5+10)*8(sp)
1107         lfd     fa2,LA_SIZE+(5+12)*8(sp)
1108         lfd     fa3,LA_SIZE+(5+14)*8(sp)
1109         lfd     fa4,LA_SIZE+(5+16)*8(sp)
1110         lfd     fa5,LA_SIZE+(5+18)*8(sp)
1111         lfd     fa6,LA_SIZE+(5+20)*8(sp)
1112         lfd     fa7,LA_SIZE+(5+22)*8(sp)
1113         lfd     fa8,LA_SIZE+(5+24)*8(sp)
1114         lfd     fa9,LA_SIZE+(5+26)*8(sp)
1115         lfd     fa10,LA_SIZE+(5+28)*8(sp)
1116         lfd     fa11,LA_SIZE+(5+30)*8(sp)
1117         lfd     fa12,LA_SIZE+(5+32)*8(sp)
1118
1119         lwz     t0,LA_SIZE+(+5+33)*8(r1)
1120         lwz     t1,LA_SIZE+(+5+34)*8(r1)
1121         lwz     t2,LA_SIZE+(+5+35)*8(r1)
1122         lwz     t3,LA_SIZE+(+5+36)*8(r1)
1123         lwz     t4,LA_SIZE+(+5+37)*8(r1)
1124         lwz     t5,LA_SIZE+(+5+38)*8(r1)
1125         lwz     t6,LA_SIZE+(+5+39)*8(r1)
1126         lwz     t7,LA_SIZE+(+5+40)*8(r1)
1127
1128         lfd     ft0,LA_SIZE+(+5+42)*8(r1)
1129         lfd     ft1,LA_SIZE+(+5+44)*8(r1)
1130         lfd     ft2,LA_SIZE+(+5+46)*8(r1)
1131         lfd     ft3,LA_SIZE+(+5+48)*8(r1)
1132         lfd     ft4,LA_SIZE+(+5+50)*8(r1)
1133         lfd     ft5,LA_SIZE+(+5+52)*8(r1)
1134 #else
1135         RESTORE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS) /* restore 8 int/8 float args  */
1136         RESTORE_TEMPORARY_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS+ARG_CNT)
1137 #endif
1138
1139         ld     itmp1,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+1*8(sp)
1140         ld     itmp2,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+2*8(sp)
1141         ld     pv,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+3*8(sp)
1142         ld     itmp3,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+4*8(sp)
1143
1144         ld      r0,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+6*8(sp) /* restore RA                      */
1145         mtlr    r0
1146
1147         mr.     itmp3,itmp3           /* check for an exception                   */
1148         bne     L_asm_patcher_wrapper_exception
1149
1150                                       /* get return address (into JIT code)       */
1151         ld     itmp3,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+5*8(sp)
1152
1153                                       /* remove stack frame + patcher stub stack  */
1154         addi    sp,sp,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+8*8
1155
1156         mtctr   itmp3
1157         bctr                          /* jump to new patched code                 */
1158
1159 L_asm_patcher_wrapper_exception:
1160         mr      xptr,itmp3                  /* get exception                      */
1161         ld      xpc,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+5*8(sp)
1162         addi    sp,sp,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+8*8
1163         b       L_asm_handle_exception
1164
1165
1166 /* asm_replacement_out *********************************************************
1167
1168    This code is jumped to from the replacement-out stubs that are executed
1169    when a thread reaches an activated replacement point.
1170
1171    The purpose of asm_replacement_out is to read out the parts of the
1172    execution state that cannot be accessed from C code, store this state,
1173    and then call the C function replace_me.
1174
1175    Stack layout:
1176       16                start of stack inside method to replace
1177       0   rplpoint *    info on the replacement point that was reached
1178
1179    NOTE: itmp3 has been clobbered by the replacement-out stub!
1180
1181 *******************************************************************************/
1182
1183 /* some room to accomodate changes of the stack frame size during replacement */
1184         /* XXX we should find a cleaner solution here */
1185 #define REPLACEMENT_ROOM  512
1186
1187 asm_replacement_out:
1188     /* create stack frame */
1189         addi    sp,sp,-(sizeexecutionstate + REPLACEMENT_ROOM) /* XXX align */
1190
1191         /* save link register */
1192         mflr    r16
1193
1194         /* save registers in execution state */
1195         stw     r0 ,( 0*8+offes_intregs)(sp)
1196         stw     r1 ,( 1*8+offes_intregs)(sp)
1197         stw     r2 ,( 2*8+offes_intregs)(sp)
1198         stw     r3 ,( 3*8+offes_intregs)(sp)
1199         stw     r4 ,( 4*8+offes_intregs)(sp)
1200         stw     r5 ,( 5*8+offes_intregs)(sp)
1201         stw     r6 ,( 6*8+offes_intregs)(sp)
1202         stw     r7 ,( 7*8+offes_intregs)(sp)
1203         stw     r8 ,( 8*8+offes_intregs)(sp)
1204         stw     r9 ,( 9*8+offes_intregs)(sp)
1205         stw     r10,(10*8+offes_intregs)(sp)
1206         stw     r11,(11*8+offes_intregs)(sp)
1207         stw     r12,(12*8+offes_intregs)(sp)
1208         stw     r13,(13*8+offes_intregs)(sp)
1209         stw     r14,(14*8+offes_intregs)(sp)
1210         stw     r15,(15*8+offes_intregs)(sp)
1211         stw     r16,(16*8+offes_intregs)(sp) /* link register */
1212         stw     r17,(17*8+offes_intregs)(sp)
1213         stw     r18,(18*8+offes_intregs)(sp)
1214         stw     r19,(19*8+offes_intregs)(sp)
1215         stw     r20,(20*8+offes_intregs)(sp)
1216         stw     r21,(21*8+offes_intregs)(sp)
1217         stw     r22,(22*8+offes_intregs)(sp)
1218         stw     r23,(23*8+offes_intregs)(sp)
1219         stw     r24,(24*8+offes_intregs)(sp)
1220         stw     r25,(25*8+offes_intregs)(sp)
1221         stw     r26,(26*8+offes_intregs)(sp)
1222         stw     r27,(27*8+offes_intregs)(sp)
1223         stw     r28,(28*8+offes_intregs)(sp)
1224         stw     r29,(29*8+offes_intregs)(sp)
1225         stw     r30,(30*8+offes_intregs)(sp)
1226         stw     r31,(31*8+offes_intregs)(sp)
1227         
1228         stfd    fr0 ,( 0*8+offes_fltregs)(sp)
1229         stfd    fr1 ,( 1*8+offes_fltregs)(sp)
1230         stfd    fr2 ,( 2*8+offes_fltregs)(sp)
1231         stfd    fr3 ,( 3*8+offes_fltregs)(sp)
1232         stfd    fr4 ,( 4*8+offes_fltregs)(sp)
1233         stfd    fr5 ,( 5*8+offes_fltregs)(sp)
1234         stfd    fr6 ,( 6*8+offes_fltregs)(sp)
1235         stfd    fr7 ,( 7*8+offes_fltregs)(sp)
1236         stfd    fr8 ,( 8*8+offes_fltregs)(sp)
1237         stfd    fr9 ,( 9*8+offes_fltregs)(sp)
1238         stfd    fr10,(10*8+offes_fltregs)(sp)
1239         stfd    fr11,(11*8+offes_fltregs)(sp)
1240         stfd    fr12,(12*8+offes_fltregs)(sp)
1241         stfd    fr13,(13*8+offes_fltregs)(sp)
1242         stfd    fr14,(14*8+offes_fltregs)(sp)
1243         stfd    fr15,(15*8+offes_fltregs)(sp)
1244         stfd    fr16,(16*8+offes_fltregs)(sp)
1245         stfd    fr17,(17*8+offes_fltregs)(sp)
1246         stfd    fr18,(18*8+offes_fltregs)(sp)
1247         stfd    fr19,(19*8+offes_fltregs)(sp)
1248         stfd    fr20,(20*8+offes_fltregs)(sp)
1249         stfd    fr21,(21*8+offes_fltregs)(sp)
1250         stfd    fr22,(22*8+offes_fltregs)(sp)
1251         stfd    fr23,(23*8+offes_fltregs)(sp)
1252         stfd    fr24,(24*8+offes_fltregs)(sp)
1253         stfd    fr25,(25*8+offes_fltregs)(sp)
1254         stfd    fr26,(26*8+offes_fltregs)(sp)
1255         stfd    fr27,(27*8+offes_fltregs)(sp)
1256         stfd    fr28,(28*8+offes_fltregs)(sp)
1257         stfd    fr29,(29*8+offes_fltregs)(sp)
1258         stfd    fr30,(30*8+offes_fltregs)(sp)
1259         stfd    fr31,(31*8+offes_fltregs)(sp)
1260         
1261         /* calculate sp of method */
1262         addi    itmp1,sp,(sizeexecutionstate + REPLACEMENT_ROOM + 4*4)
1263         stw     itmp1,(offes_sp)(sp)
1264
1265         /* store pv */
1266         stw     pv,(offes_pv)(sp)
1267
1268         /* call replace_me */
1269         lwz     a0,-(4*4)(itmp1)            /* arg0: rplpoint *                   */
1270         mr      a1,sp                       /* arg1: execution state              */
1271         addi    sp,sp,-(LA_SIZE_ALIGNED)
1272         b       replace_me                  /* call C function replace_me         */
1273
1274 /* asm_replacement_in **********************************************************
1275
1276    This code writes the given execution state and jumps to the replacement
1277    code.
1278
1279    This function never returns!
1280
1281    NOTE: itmp3 is not restored!
1282
1283    C prototype:
1284       void asm_replacement_in(executionstate *es);
1285
1286 *******************************************************************************/
1287
1288 .asm_replacement_in:
1289         /* a0 == executionstate *es */
1290
1291         /* set new sp and pv */
1292         lwz     sp,(offes_sp)(a0)
1293         lwz     pv,(offes_pv)(a0)
1294         
1295         /* copy registers from execution state */
1296         lwz     r0 ,( 0*8+offes_intregs)(a0)
1297         /* r1 is sp                       */
1298         /* r2 is reserved                 */
1299         /* a0 is loaded below             */
1300         lwz     r4 ,( 4*8+offes_intregs)(a0)
1301         lwz     r5 ,( 5*8+offes_intregs)(a0)
1302         lwz     r6 ,( 6*8+offes_intregs)(a0)
1303         lwz     r7 ,( 7*8+offes_intregs)(a0)
1304         lwz     r8 ,( 8*8+offes_intregs)(a0)
1305         lwz     r9 ,( 9*8+offes_intregs)(a0)
1306         lwz     r10,(10*8+offes_intregs)(a0)
1307         lwz     r11,(11*8+offes_intregs)(a0)
1308         lwz     r12,(12*8+offes_intregs)(a0)
1309         /* r13 is pv                      */
1310         lwz     r14,(14*8+offes_intregs)(a0)
1311         lwz     r15,(15*8+offes_intregs)(a0)
1312         lwz     r16,(16*8+offes_intregs)(a0) /* link register */
1313         lwz     r17,(17*8+offes_intregs)(a0)
1314         lwz     r18,(18*8+offes_intregs)(a0)
1315         lwz     r19,(19*8+offes_intregs)(a0)
1316         lwz     r20,(20*8+offes_intregs)(a0)
1317         lwz     r21,(21*8+offes_intregs)(a0)
1318         lwz     r22,(22*8+offes_intregs)(a0)
1319         lwz     r23,(23*8+offes_intregs)(a0)
1320         lwz     r24,(24*8+offes_intregs)(a0)
1321         lwz     r25,(25*8+offes_intregs)(a0)
1322         lwz     r26,(26*8+offes_intregs)(a0)
1323         lwz     r27,(27*8+offes_intregs)(a0)
1324         lwz     r28,(28*8+offes_intregs)(a0)
1325         lwz     r29,(29*8+offes_intregs)(a0)
1326         lwz     r30,(30*8+offes_intregs)(a0)
1327         lwz     r31,(31*8+offes_intregs)(a0)
1328         
1329         lfd     fr0 ,( 0*8+offes_fltregs)(a0)
1330         lfd     fr1 ,( 1*8+offes_fltregs)(a0)
1331         lfd     fr2 ,( 2*8+offes_fltregs)(a0)
1332         lfd     fr3 ,( 3*8+offes_fltregs)(a0)
1333         lfd     fr4 ,( 4*8+offes_fltregs)(a0)
1334         lfd     fr5 ,( 5*8+offes_fltregs)(a0)
1335         lfd     fr6 ,( 6*8+offes_fltregs)(a0)
1336         lfd     fr7 ,( 7*8+offes_fltregs)(a0)
1337         lfd     fr8 ,( 8*8+offes_fltregs)(a0)
1338         lfd     fr9 ,( 9*8+offes_fltregs)(a0)
1339         lfd     fr10,(10*8+offes_fltregs)(a0)
1340         lfd     fr11,(11*8+offes_fltregs)(a0)
1341         lfd     fr12,(12*8+offes_fltregs)(a0)
1342         lfd     fr13,(13*8+offes_fltregs)(a0)
1343         lfd     fr14,(14*8+offes_fltregs)(a0)
1344         lfd     fr15,(15*8+offes_fltregs)(a0)
1345         lfd     fr16,(16*8+offes_fltregs)(a0)
1346         lfd     fr17,(17*8+offes_fltregs)(a0)
1347         lfd     fr18,(18*8+offes_fltregs)(a0)
1348         lfd     fr19,(19*8+offes_fltregs)(a0)
1349         lfd     fr20,(20*8+offes_fltregs)(a0)
1350         lfd     fr21,(21*8+offes_fltregs)(a0)
1351         lfd     fr22,(22*8+offes_fltregs)(a0)
1352         lfd     fr23,(23*8+offes_fltregs)(a0)
1353         lfd     fr24,(24*8+offes_fltregs)(a0)
1354         lfd     fr25,(25*8+offes_fltregs)(a0)
1355         lfd     fr26,(26*8+offes_fltregs)(a0)
1356         lfd     fr27,(27*8+offes_fltregs)(a0)
1357         lfd     fr28,(28*8+offes_fltregs)(a0)
1358         lfd     fr29,(29*8+offes_fltregs)(a0)
1359         lfd     fr30,(30*8+offes_fltregs)(a0)
1360         lfd     fr31,(31*8+offes_fltregs)(a0)
1361
1362         /* restore link register */
1363
1364         mtlr    r16
1365         
1366         /* load new pc */
1367
1368         lwz     itmp3,offes_pc(a0)
1369
1370         /* load a0 */
1371         
1372         lwz     a0,(3*8+offes_intregs)(a0)
1373
1374         /* jump to new code */
1375
1376         mtctr   itmp3
1377         bctr
1378
1379 /*********************************************************************/
1380 /*
1381 asm_cacheflush:
1382         .quad .asm_cacheflush,.TOC.@tocbase,0
1383         .previous
1384         .size asm_cacheflush,24
1385         .type .asm_cacheflush,@function
1386         .globl .asm_cacheflush
1387 */
1388 .asm_cacheflush:
1389         add     r4,r3,r4
1390         rldimi  r3,r3,0,26
1391         addi    r4,r4,31
1392         rldimi  r4,r4,0,26
1393         mr      r5,r3
1394 1:
1395         cmpld   r3,r4
1396         bge     0f
1397         dcbst   0,r3
1398         addi    r3,r3,32
1399         b       1b
1400 0:
1401         sync
1402 1:
1403         cmpld   r5,r4
1404         bge     0f
1405         icbi    0,r5
1406         addi    r5,r5,32
1407         b       1b
1408 0:
1409         sync
1410         isync
1411         blr
1412
1413
1414 .asm_getclassvalues_atomic:
1415 _crit_restart:
1416 _crit_begin:
1417         lwz     r6,offbaseval(r3)
1418         lwz     r7,offdiffval(r3)
1419         lwz     r8,offbaseval(r4)
1420 _crit_end:
1421         stw     r6,offcast_super_baseval(r5)
1422         stw     r7,offcast_super_diffval(r5)
1423         stw     r8,offcast_sub_baseval(r5)
1424         blr
1425
1426         .data
1427
1428 asm_criticalsections:
1429 #if defined(ENABLE_THREADS)
1430         .quad   _crit_begin
1431         .quad   _crit_end
1432         .quad   _crit_restart
1433 #endif
1434         .quad 0
1435
1436
1437 #if defined(__DARWIN__)
1438
1439 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1440         .align 2
1441 L_builtin_throw_exception$stub:
1442         .indirect_symbol _builtin_throw_exception
1443         mflr r0
1444         bcl 20,31,L00$_builtin_throw_exception
1445 L00$_builtin_throw_exception:
1446         mflr r11
1447         addis r11,r11,ha16(L_builtin_throw_exception$lazy_ptr - L00$_builtin_throw_exception)
1448         mtlr r0
1449         lwzu r12,lo16(L_builtin_throw_exception$lazy_ptr - L00$_builtin_throw_exception)(r11)
1450         mtctr r12
1451         bctr
1452 .data
1453 .lazy_symbol_pointer
1454 L_builtin_throw_exception$lazy_ptr:
1455         .indirect_symbol _builtin_throw_exception
1456         .long dyld_stub_binding_helper
1457
1458
1459 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1460         .align 2
1461 L_exceptions_handle_exception$stub:
1462         .indirect_symbol _exceptions_handle_exception
1463         mflr r0
1464         bcl 20,31,L00$_exceptions_handle_exception
1465 L00$_exceptions_handle_exception:
1466         mflr r11
1467         addis r11,r11,ha16(L_exceptions_handle_exception$lazy_ptr - L00$_exceptions_handle_exception)
1468         mtlr r0
1469         lwzu r12,lo16(L_exceptions_handle_exception$lazy_ptr - L00$_exceptions_handle_exception)(r11)
1470         mtctr r12
1471         bctr
1472 .data
1473 .lazy_symbol_pointer
1474 L_exceptions_handle_exception$lazy_ptr:
1475         .indirect_symbol _exceptions_handle_exception
1476         .long dyld_stub_binding_helper
1477
1478
1479 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1480         .align 2
1481 L_stacktrace_create_extern_stackframeinfo$stub:
1482         .indirect_symbol _stacktrace_create_extern_stackframeinfo
1483         mflr r0
1484         bcl 20,31,L00$_stacktrace_create_extern_stackframeinfo
1485 L00$_stacktrace_create_extern_stackframeinfo:
1486         mflr r11
1487         addis r11,r11,ha16(L_stacktrace_create_extern_stackframeinfo$lazy_ptr - L00$_stacktrace_create_extern_stackframeinfo)
1488         mtlr r0
1489         lwzu r12,lo16(L_stacktrace_create_extern_stackframeinfo$lazy_ptr - L00$_stacktrace_create_extern_stackframeinfo)(r11)
1490         mtctr r12
1491         bctr
1492 .data
1493 .lazy_symbol_pointer
1494 L_stacktrace_create_extern_stackframeinfo$lazy_ptr:
1495         .indirect_symbol _stacktrace_create_extern_stackframeinfo
1496         .long dyld_stub_binding_helper
1497
1498
1499 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1500         .align 2
1501 L_jit_asm_compile$stub:
1502         .indirect_symbol _jit_asm_compile
1503         mflr r0
1504         bcl 20,31,L00$_jit_asm_compile
1505 L00$_jit_asm_compile:
1506         mflr r11
1507         addis r11,r11,ha16(L_jit_asm_compile$lazy_ptr - L00$_jit_asm_compile)
1508         mtlr r0
1509         lwzu r12,lo16(L_jit_asm_compile$lazy_ptr - L00$_jit_asm_compile)(r11)
1510         mtctr r12
1511         bctr
1512 .data
1513 .lazy_symbol_pointer
1514 L_jit_asm_compile$lazy_ptr:
1515         .indirect_symbol _jit_asm_compile
1516         .long dyld_stub_binding_helper
1517
1518
1519 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1520         .align 2
1521 L_stacktrace_remove_stackframeinfo$stub:
1522         .indirect_symbol _stacktrace_remove_stackframeinfo
1523         mflr r0
1524         bcl 20,31,L00$_stacktrace_remove_stackframeinfo
1525 L00$_stacktrace_remove_stackframeinfo:
1526         mflr r11
1527         addis r11,r11,ha16(L_stacktrace_remove_stackframeinfo$lazy_ptr - L00$_stacktrace_remove_stackframeinfo)
1528         mtlr r0
1529         lwzu r12,lo16(L_stacktrace_remove_stackframeinfo$lazy_ptr - L00$_stacktrace_remove_stackframeinfo)(r11)
1530         mtctr r12
1531         bctr
1532 .data
1533 .lazy_symbol_pointer
1534 L_stacktrace_remove_stackframeinfo$lazy_ptr:
1535         .indirect_symbol _stacktrace_remove_stackframeinfo
1536         .long dyld_stub_binding_helper
1537
1538
1539 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1540         .align 2
1541 L_exceptions_get_and_clear_exception$stub:
1542         .indirect_symbol _exceptions_get_and_clear_exception
1543         mflr r0
1544         bcl 20,31,L00$_exceptions_get_and_clear_exception
1545 L00$_exceptions_get_and_clear_exception:
1546         mflr r11
1547         addis r11,r11,ha16(L_exceptions_get_and_clear_exception$lazy_ptr - L00$_exceptions_get_and_clear_exception)
1548         mtlr r0
1549         lwzu r12,lo16(L_exceptions_get_and_clear_exception$lazy_ptr - L00$_exceptions_get_and_clear_exception)(r11)
1550         mtctr r12
1551         bctr
1552 .data
1553 .lazy_symbol_pointer
1554 L_exceptions_get_and_clear_exception$lazy_ptr:
1555         .indirect_symbol _exceptions_get_and_clear_exception
1556         .long dyld_stub_binding_helper
1557
1558
1559 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1560         .align 2
1561 L_exceptions_asm_new_abstractmethoderror$stub:
1562         .indirect_symbol _exceptions_asm_new_abstractmethoderror
1563         mflr r0
1564         bcl 20,31,L00$_exceptions_asm_new_abstractmethoderror
1565 L00$_exceptions_asm_new_abstractmethoderror:
1566         mflr r11
1567         addis r11,r11,ha16(L_exceptions_asm_new_abstractmethoderror$lazy_ptr - L00$_exceptions_asm_new_abstractmethoderror)
1568         mtlr r0
1569         lwzu r12,lo16(L_exceptions_asm_new_abstractmethoderror$lazy_ptr - L00$_exceptions_asm_new_abstractmethoderror)(r11)
1570         mtctr r12
1571         bctr
1572 .data
1573 .lazy_symbol_pointer
1574 L_exceptions_asm_new_abstractmethoderror$lazy_ptr:
1575         .indirect_symbol _exceptions_asm_new_abstractmethoderror
1576         .long dyld_stub_binding_helper
1577
1578
1579 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1580         .align 2
1581 L_patcher_wrapper$stub:
1582         .indirect_symbol _patcher_wrapper
1583         mflr r0
1584         bcl 20,31,L00$_patcher_wrapper
1585 L00$_patcher_wrapper:
1586         mflr r11
1587         addis r11,r11,ha16(L_patcher_wrapper$lazy_ptr - L00$_patcher_wrapper)
1588         mtlr r0
1589         lwzu r12,lo16(L_patcher_wrapper$lazy_ptr - L00$_patcher_wrapper)(r11)
1590         mtctr r12
1591         bctr
1592 .data
1593 .lazy_symbol_pointer
1594 L_patcher_wrapper$lazy_ptr:
1595         .indirect_symbol _patcher_wrapper
1596         .long dyld_stub_binding_helper
1597
1598
1599 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1600         .align 2
1601 L_replace_me$stub:
1602         .indirect_symbol _replace_me
1603         mflr r0
1604         bcl 20,31,L00$_replace_me
1605 L00$_replace_me:
1606         mflr r11
1607         addis r11,r11,ha16(L_replace_me$lazy_ptr - L00$_replace_me)
1608         mtlr r0
1609         lwzu r12,lo16(L_replace_me$lazy_ptr - L00$_replace_me)(r11)
1610         mtctr r12
1611         bctr
1612 .data
1613 .lazy_symbol_pointer
1614 L_replace_me$lazy_ptr:
1615         .indirect_symbol _replace_me
1616         .long dyld_stub_binding_helper
1617
1618 #endif /* defined(__DARWIN__) */
1619
1620
1621 /* Disable exec-stacks, required for Gentoo ***********************************/
1622
1623 #if defined(__GCC__) && defined(__ELF__)
1624         .section .note.GNU-stack,"",@progbits
1625 #endif
1626
1627
1628 /*
1629  * These are local overrides for various environment variables in Emacs.
1630  * Please do not remove this and leave it at the end of the file, where
1631  * Emacs will automagically detect them.
1632  * ---------------------------------------------------------------------
1633  * Local variables:
1634  * mode: asm
1635  * indent-tabs-mode: t
1636  * c-basic-offset: 4
1637  * tab-width: 4
1638  * End:
1639  * vim:noexpandtab:sw=4:ts=4:
1640  */