GNU header update.
[cacao.git] / src / vm / jit / x86_64 / asmpart.S
1 /* vm/jit/x86_64/asmpart.S - Java-C interface functions for x86_64
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Andreas Krall
28             Reinhard Grafl
29             Christian Thalinger
30
31    $Id: asmpart.S 1735 2004-12-07 14:33:27Z twisti $
32
33 */
34
35
36 #include "config.h"
37 #include "vm/jit/x86_64/arch.h"
38 #include "vm/jit/x86_64/offsets.h"
39 #include "vm/jit/x86_64/asmoffsets.h"
40
41
42 /* define it like the risc way */
43
44 #define v0       %rax
45
46 #define a0       %rdi
47 #define a1       %rsi
48 #define a2       %rdx
49 #define a3       %rcx
50 #define a4       %r8
51 #define a5       %r9
52
53 #define fa0      %xmm0
54 #define fa1      %xmm1
55 #define fa2      %xmm2
56 #define fa3      %xmm3
57 #define fa4      %xmm4
58 #define fa5      %xmm5
59 #define fa6      %xmm6
60 #define fa7      %xmm7
61
62 #define itmp1    %rax
63 #define itmp2    %r10
64 #define itmp3    %r11
65
66 #define itmp1l   %eax
67 #define itmp2l   %r10d
68 #define itmp3l   %r11d
69
70 #define itmp1b   %al
71 #define itmp2b   %r10b
72 #define itmp3b   %r11b
73
74 #define xptr     itmp1
75 #define xpc      itmp2
76
77
78         .text
79
80
81 /********************* exported functions and variables ***********************/
82
83         .globl asm_calljavafunction
84         .globl calljava_xhandler
85         .globl asm_calljavafunction2
86         .globl asm_calljavafunction2long
87         .globl asm_calljavafunction2double
88         .globl calljava_xhandler2
89         .globl asm_call_jit_compiler
90         .globl asm_handle_exception
91         .globl asm_handle_nat_exception
92         .globl asm_check_clinit
93         .globl asm_builtin_checkarraycast
94         .globl asm_builtin_anewarray
95         .globl asm_builtin_newarray_array
96         .globl asm_builtin_aastore
97         .globl asm_builtin_monitorenter
98         .globl asm_builtin_monitorexit
99         .globl asm_builtin_f2i
100         .globl asm_builtin_f2l
101         .globl asm_builtin_d2i
102         .globl asm_builtin_d2l
103         .globl asm_builtin_arrayinstanceof
104         .globl asm_perform_threadswitch
105         .globl asm_initialize_thread_stack
106         .globl asm_switchstackandcall
107         .globl asm_criticalsections
108         .globl asm_getclassvalues_atomic
109                 
110
111 /*************************** imported functions *******************************/
112
113         .globl jit_compile
114         .globl builtin_monitorexit
115         .globl builtin_throw_exception
116         .globl builtin_trace_exception
117         .globl codegen_findmethod
118         
119
120 /********************* function asm_calljavafunction ***************************
121 *                                                                              *
122 *   This function calls a Java-method (which possibly needs compilation)       *
123 *   with up to 4 address parameters.                                           *
124 *                                                                              *
125 *   This functions calls the JIT-compiler which eventually translates the      *
126 *   method into machine code.                                                  *
127 *                                                                              *
128 *   C-prototype:                                                               *
129 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
130 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
131 *                                                                              *
132 *******************************************************************************/
133
134 call_name:
135         .align  8
136
137         .quad   0                         /* catch type all                       */
138         .quad   calljava_xhandler         /* handler pc                           */
139         .quad   calljava_xhandler         /* end pc                               */
140         .quad   asm_calljavafunction      /* start pc                             */
141         .long   1                         /* extable size                         */
142         .long   0                         /* fltsave                              */
143         .long   0                         /* intsave                              */
144         .long   0                         /* isleaf                               */
145         .long   0                         /* IsSync                               */
146         .long   8                         /* frame size                           */
147         .quad   0                         /* method pointer (pointer to name)     */
148
149 asm_calljavafunction:
150         sub     $(3*8),%rsp               /* keep stack 16-byte aligned           */
151         mov     %rbp,0*8(%rsp)
152         mov     %rbx,1*8(%rsp)            /* %rbx is not a callee saved in cacao  */
153         mov     %rdi,%rax                 /* move function pointer to %rax        */
154                                                                           /* compilerstub uses this               */
155
156         mov     %rsi,%rdi                 /* pass remaining parameters            */
157         mov     %rdx,%rsi
158         mov     %rcx,%rdx
159         mov     %r8,%rcx
160         
161         lea     asm_call_jit_compiler,%r11
162         call    *%r11                     /* call JIT compiler                    */
163
164         mov     0*8(%rsp),%rbp
165         mov             1*8(%rsp),%rbx
166         add     $(3*8),%rsp              /* free stack space                     */
167         ret
168
169 calljava_xhandler:
170         mov     %rax,%rdi                /* pass exception pointer               */
171         call    builtin_throw_exception
172         mov     0*8(%rsp),%rbp
173         mov             1*8(%rsp),%rbx
174         add     $(3*8),%rsp
175         ret
176
177
178 /********************* function asm_calljavafunction ***************************
179 *                                                                              *
180 *   This function calls a Java-method (which possibly needs compilation)       *
181 *   with up to 4 address parameters.                                           *
182 *                                                                              *
183 *   This functions calls the JIT-compiler which eventually translates the      *
184 *   method into machine code.                                                  *
185 *                                                                              *
186 *   C-prototype:                                                               *
187 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
188 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
189 *                                                                              *
190 *******************************************************************************/
191
192 call_name2:
193         .align  8
194
195         .quad   0                         /* catch type all                       */
196         .quad   calljava_xhandler2        /* handler pc                           */
197         .quad   calljava_xhandler2        /* end pc                               */
198         .quad   asm_calljavafunction2     /* start pc                             */
199         .long   1                         /* extable size                         */
200         .long   0                         /* fltsave                              */
201         .long   0                         /* intsave                              */
202         .long   0                         /* isleaf                               */
203         .long   0                         /* IsSync                               */
204         .long   24                        /* frame size                           */
205         .quad   0                         /* method pointer (pointer to name)     */
206
207 asm_calljavafunction2:
208 asm_calljavafunction2double:
209 asm_calljavafunction2long:
210         sub     $(7*8),%rsp               /* keep stack 16-byte aligned           */
211         mov     %rbx,0*8(%rsp)            /* %rbx is not a callee saved in cacao  */
212         mov     %rbp,1*8(%rsp)
213         mov     %r12,2*8(%rsp)
214         mov     %r13,3*8(%rsp)
215         mov     %r14,4*8(%rsp)
216         mov     %r15,5*8(%rsp)
217
218         mov     %rdi,%rax                 /* move method pointer for compiler     */
219
220         mov     %rsi,itmp3                /* arg count                            */
221         mov     %rcx,itmp2                /* pointer to arg block                 */
222                 
223         test    itmp3,itmp3               /* maybe we have no args...             */
224         jle     L_copy_done
225
226         mov     itmp2,%r14                /* save argument block pointer          */
227         mov     itmp3,%r15                /* save argument count                  */
228
229         sub     $sizejniblock,itmp2       /* initialize pointer (smaller code)    */
230         add     $1,itmp3                  /* initialize argument count            */
231         xor     %r12,%r12                 /* initialize integer argument counter  */
232         xor     %r13,%r13                 /* initialize float argument counter    */
233
234 L_register_copy:
235         add     $sizejniblock,itmp2       /* goto next argument block             */
236         dec     itmp3                     /* argument count - 1                   */
237         jz      L_register_copy_done
238         andb    $0x02,offjniitemtype(itmp2) /* is this a float/double type?       */
239         jnz     L_register_handle_float   /* yes, handle it                       */
240
241         cmp     $(INT_ARG_CNT - 1),%r12   /* are we out of integer argument       */
242         je      L_register_copy           /* register? yes, next loop             */
243
244         lea     jumptable_integer,%rbp
245         mov     0(%rbp,%r12,8),%rbx
246         inc     %r12                      /* integer argument counter + 1         */
247         jmp     *%rbx
248
249 L_register_handle_float:
250         cmp     $(FLT_ARG_CNT - 1),%r13   /* are we out of float argument         */
251         je      L_register_copy           /* register? yes, next loop             */
252
253         lea     jumptable_float,%rbp
254         mov     0(%rbp,%r13,8),%rbx
255         inc     %r13                      /* float argument counter + 1           */
256         jmp     *%rbx
257         
258 L_register_copy_done:
259         mov     %r15,itmp3                /* calculate remaining arguments after  */
260         sub     %r12,itmp3                /* register copy                        */
261         sub     %r13,itmp3
262         jle     L_copy_done               /* are all assigned to registers?       */
263
264         shl     $3,itmp3                  /* calculate stack size                 */
265         sub     itmp3,%rsp                /* stack frame for arguments            */
266         mov     %rsp,%rbx                 /* use %rbx as temp sp                  */
267
268         sub     $sizejniblock,itmp2       /* initialize pointer (smaller code)    */
269         add     $1,%r15                   /* initialize argument count            */
270                 
271 L_stack_copy_loop:
272         add     $sizejniblock,itmp2       /* goto next argument block             */
273         dec     %r15                      /* are there any arguments left?        */
274         jz      L_copy_done               /* no test needed after dec             */
275
276         andb    $0x02,offjniitemtype(itmp2) /* is this a float/double type?       */
277         jnz     L_stack_handle_float
278         dec     %r12                      /* arguments assigned to registers      */
279         jge     L_stack_copy_loop
280         jmp     L_stack_copy
281
282 L_stack_handle_float:
283         dec     %r13                      /* arguments assigned to registers      */
284         jge     L_stack_copy_loop
285
286 L_stack_copy:
287     mov     offjniitem(itmp2),itmp3   /* copy s8 argument onto stack          */
288     mov     itmp3,0(%rbx)
289     add     $8,%rbx                   /* increase sp to next argument         */
290         jmp     L_stack_copy_loop
291
292 L_copy_done:
293         lea     asm_call_jit_compiler,%r11/* %rax still contains method pointer   */
294         call    *%r11                     /* call JIT compiler                    */
295
296         mov     5*8(%rsp),%r15            /* restore callee saved registers       */
297         mov     4*8(%rsp),%r14
298         mov     3*8(%rsp),%r13
299         mov     2*8(%rsp),%r12
300         mov     1*8(%rsp),%rbp
301         mov     0*8(%rsp),%rbx
302         add     $(7*8),%rsp               /* free stack space                     */
303         ret
304                 
305 calljava_xhandler2:
306         mov     %rax,%rdi                 /* pass exception pointer               */
307         call    builtin_throw_exception
308
309         mov     5*8(%rsp),%r15            /* restore callee saved registers       */
310         mov     4*8(%rsp),%r14
311         mov     3*8(%rsp),%r13
312         mov     2*8(%rsp),%r12
313         mov     1*8(%rsp),%rbp
314         mov     0*8(%rsp),%rbx
315         add     $(7*8),%rsp               /* free stack space                     */
316         ret
317
318
319 jumptable_integer:
320         .quad   handle_a0
321         .quad   handle_a1
322         .quad   handle_a2
323         .quad   handle_a3
324         .quad   handle_a4
325         .quad   handle_a5
326
327 handle_a0:
328         mov     offjniitem(itmp2),a0
329         jmp     L_register_copy
330 handle_a1:
331         mov     offjniitem(itmp2),a1
332         jmp     L_register_copy
333 handle_a2:
334         mov     offjniitem(itmp2),a2
335         jmp     L_register_copy
336 handle_a3:
337         mov     offjniitem(itmp2),a3
338         jmp     L_register_copy
339 handle_a4:
340         mov     offjniitem(itmp2),a4
341         jmp     L_register_copy
342 handle_a5:
343         mov     offjniitem(itmp2),a5
344         jmp     L_register_copy
345
346
347 jumptable_float:
348         .quad   handle_fa0
349         .quad   handle_fa1
350         .quad   handle_fa2
351         .quad   handle_fa3
352         .quad   handle_fa4
353         .quad   handle_fa5
354         .quad   handle_fa6
355         .quad   handle_fa7
356
357 handle_fa0:
358         movq    offjniitem(itmp2),fa0
359         jmp     L_register_copy
360 handle_fa1:
361         movq    offjniitem(itmp2),fa1
362         jmp     L_register_copy
363 handle_fa2:
364         movq    offjniitem(itmp2),fa2
365         jmp     L_register_copy
366 handle_fa3:
367         movq    offjniitem(itmp2),fa3
368         jmp     L_register_copy
369 handle_fa4:
370         movq    offjniitem(itmp2),fa4
371         jmp     L_register_copy
372 handle_fa5:
373         movq    offjniitem(itmp2),fa5
374         jmp     L_register_copy
375 handle_fa6:
376         movq    offjniitem(itmp2),fa6
377         jmp     L_register_copy
378 handle_fa7:
379         movq    offjniitem(itmp2),fa7
380         jmp     L_register_copy
381
382
383 /****************** function asm_call_jit_compiler *****************************
384 *                                                                              *
385 *   invokes the compiler for untranslated JavaVM methods.                      *
386 *                                                                              *
387 *   Register R0 contains a pointer to the method info structure (prepared      *
388 *   by createcompilerstub). Using the return address in R26 and the            *
389 *   offset in the LDA instruction or using the value in methodptr R28 the      *
390 *   patching address for storing the method address can be computed:           *
391 *                                                                              *
392 *   method address was either loaded using                                     *
393 *                                                                              *
394 *   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special       *
395 *   i386_call_reg(REG_ITMP2)                                                   *
396 *                                                                              *
397 *   or                                                                         *
398 *                                                                              *
399 *   i386_mov_membase_reg(REG_SP, 0, REG_ITMP2)    ; invokevirtual/interface    *
400 *   i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3)                *
401 *   i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \                *
402 *       sizeof(methodptr) * m->vftblindex, REG_ITMP1)                          *
403 *   i386_call_reg(REG_ITMP1)                                                   *
404 *                                                                              *
405 *   in the static case the method pointer can be computed using the            *
406 *   return address and the lda function following the jmp instruction          *
407 *                                                                              *
408 *******************************************************************************/
409
410 asm_call_jit_compiler:
411         sub     $8,%rsp         /* keep stack 16-byte aligned                 */
412
413         mov     %rbx,(%rsp)     /* save register                              */
414         
415         mov     8(%rsp),%r11    /* get return address                         */
416         mov     -1(%r11),%bl    /* get function code                          */
417         cmp     $0xd2,%bl               /* called with `call *REG_ITMP2' (%r10)?      */
418         jne     L_not_static_special
419
420         sub     $11,%r11        /* calculate address of immediate             */
421         jmp             L_call_jit_compile
422                 
423 L_not_static_special:
424                 cmp     $0xd0,%bl               /* called with `call *REG_ITMP1' (%rax)       */
425                 jne     L_not_virtual_interface
426                 
427                 sub     $7,%r11         /* calculate address of offset                */
428                 mov     (%r11),%r11d    /* get offset (32-bit)                        */
429                 add     %r10,%r11       /* add base address to get method address     */
430                 jmp     L_call_jit_compile
431
432 L_not_virtual_interface:        /* a call from asm_calljavamethod             */
433                 xor     %r11,%r11
434                 
435 L_call_jit_compile:
436         mov     (%rsp),%rbx     /* restore register                           */
437         
438         sub     $(24*8),%rsp    /* 8 + 48 + 64 + 64                           */
439         
440                 mov     %r11,0*8(%rsp)  /* save address for method pointer            */
441
442         mov     %rdi,1*8(%rsp)  /* save arguments                             */
443         mov     %rsi,2*8(%rsp)
444         mov     %rdx,3*8(%rsp)
445         mov     %rcx,4*8(%rsp)
446         mov     %r8,5*8(%rsp)
447         mov     %r9,6*8(%rsp)
448
449         movq    %xmm0,7*8(%rsp)
450         movq    %xmm1,8*8(%rsp)
451         movq    %xmm2,9*8(%rsp)
452         movq    %xmm3,10*8(%rsp)
453         movq    %xmm4,11*8(%rsp)
454         movq    %xmm5,12*8(%rsp)
455         movq    %xmm6,13*8(%rsp)
456         movq    %xmm7,14*8(%rsp)
457
458         movq    %xmm8,15*8(%rsp)/* we use them as callee saved registers      */
459         movq    %xmm9,16*8(%rsp)
460         movq    %xmm10,17*8(%rsp)
461         movq    %xmm11,18*8(%rsp)
462         movq    %xmm12,19*8(%rsp)
463         movq    %xmm13,20*8(%rsp)
464         movq    %xmm14,21*8(%rsp)
465         movq    %xmm15,22*8(%rsp)
466
467         mov     %rax,%rdi       /* pass method pointer                        */
468                 call    jit_compile
469
470         mov     0*8(%rsp),%r11
471         
472         mov     1*8(%rsp),%rdi
473         mov     2*8(%rsp),%rsi
474         mov     3*8(%rsp),%rdx
475         mov     4*8(%rsp),%rcx
476         mov     5*8(%rsp),%r8
477         mov     6*8(%rsp),%r9
478
479         movq    7*8(%rsp),%xmm0
480         movq    8*8(%rsp),%xmm1
481         movq    9*8(%rsp),%xmm2
482         movq    10*8(%rsp),%xmm3
483         movq    11*8(%rsp),%xmm4
484         movq    12*8(%rsp),%xmm5
485         movq    13*8(%rsp),%xmm6
486         movq    14*8(%rsp),%xmm7
487
488         movq    15*8(%rsp),%xmm8
489         movq    16*8(%rsp),%xmm9
490         movq    17*8(%rsp),%xmm10
491         movq    18*8(%rsp),%xmm11
492         movq    19*8(%rsp),%xmm12
493         movq    20*8(%rsp),%xmm13
494         movq    21*8(%rsp),%xmm14
495         movq    22*8(%rsp),%xmm15
496
497         add     $(24*8),%rsp
498
499                 test    %r11,%r11               /* is address == 0 (asm_calljavamethod)       */
500                 je              L_call_method
501                 
502                 mov     %rax,(%r11)             /* and now save the new pointer               */
503
504 L_call_method:
505         add     $8,%rsp         /* keep stack 16-byte aligned                 */
506                 jmp             *%rax                   /* ...and now call the new method             */
507
508
509 /********************* function asm_handle_exception ***************************
510 *                                                                              *
511 *   This function handles an exception. It does not use the usual calling      *
512 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
513 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
514 *   the local exception table for a handler. If no one is found, it unwinds    *
515 *   stacks and continues searching the callers.                                *
516 *                                                                              *
517 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
518 *                                                                              *
519 *******************************************************************************/
520
521 asm_handle_nat_exception:
522         add     $8,%rsp                     /* clear return address of native stub*/
523                 
524 asm_handle_exception:
525         sub     $(4*8),%rsp
526         mov     xptr,0*8(%rsp)              /* save exception pointer             */
527         mov     xpc,1*8(%rsp)               /* save exception pc                  */
528         
529         mov     xpc,%rdi                    /* exception pc                       */
530         call    codegen_findmethod
531         mov     %rax,itmp3
532         mov     %rax,2*8(%rsp)              /* save data segment pointer          */
533         
534         mov     0*8(%rsp),%rax              /* restore exception pointer          */
535         mov     1*8(%rsp),%r10              /* restore exception pc               */
536         
537 ex_stack_loop:
538         mov     %rax,%rdi                   /* exception pointer                  */
539         mov     MethodPointer(itmp3),%rsi   /* method pointer                     */
540         mov     xpc,%rdx                    /* exception pc                       */
541         mov     $0,%rcx
542         mov     $1,%r8                      /* set noindent flag                  */
543         call    builtin_trace_exception
544
545         mov     2*8(%rsp),itmp3             /* %r11 = data segment pointer        */
546         mov     ExTableSize(itmp3),%rcx     /* %rcx = exception table size        */
547         test    %rcx,%rcx                                       /* if empty table skip                */
548         je      empty_table
549
550         lea     ExTableStart(itmp3),%rdi    /* %rdi = start of exception table    */
551         mov     0*8(%rsp),xptr              /* get xptr                           */
552                 
553 ex_table_loop:
554         mov     1*8(%rsp),xpc               /* get xpc                            */
555                 
556         mov     ExStartPC(%rdi),%rdx        /* %rdx = exception start pc          */
557         cmp     xpc,%rdx                    /* %rdx = (startpc <= xpc)            */
558         jg      ex_table_cont               /* if (false) continue                */
559         mov     ExEndPC(%rdi),%rdx          /* %rdx = exception end pc            */
560         cmp     %rdx,xpc                    /* %rdx = (xpc < endpc)               */
561         jge     ex_table_cont               /* if (false) continue                */
562         mov     ExCatchType(%rdi),%rdx      /* %rdx = exception catch type        */
563         test    %rdx,%rdx                   /* NULL catches everything            */
564         je      ex_handle_it
565
566         cmpl    $0,offclassloaded(%rdx)     /* check if class is loaded           */
567         jne     L_class_loaded
568
569         sub     $(4*8),%rsp
570         mov     %rax,0*8(%rsp)
571         mov     %rcx,1*8(%rsp)
572         mov     %rdx,2*8(%rsp)
573         mov     %rdi,3*8(%rsp)
574
575         mov     %rdx,%rdi
576         call    class_load
577
578         mov     0*8(%rsp),%rax
579         mov     1*8(%rsp),%rcx
580         mov     2*8(%rsp),%rdx
581         mov     3*8(%rsp),%rdi
582         add     $(4*8),%rsp
583
584 L_class_loaded:
585         cmpl    $0,offclasslinked(%rdx)     /* check if class is linked           */
586         jne     L_class_linked
587
588         sub     $(4*8),%rsp
589         mov     %rax,0*8(%rsp)
590         mov     %rcx,1*8(%rsp)
591         mov     %rdx,2*8(%rsp)
592         mov     %rdi,3*8(%rsp)
593
594         mov     %rdx,%rdi
595         call    class_link
596
597         mov     0*8(%rsp),%rax
598         mov     1*8(%rsp),%rcx
599         mov     2*8(%rsp),%rdx
600         mov     3*8(%rsp),%rdi
601         add     $(4*8),%rsp
602
603 L_class_linked:
604 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
605         push    %rdx
606
607 _crit_restart1:
608         mov     0(%rsp),%rdx
609 #endif
610
611 _crit_begin1:
612         mov     offobjvftbl(%rax),%rsi      /* %rsi = vftblptr(xptr)              */
613         mov     offclassvftbl(%rdx),%rdx    /* %rdx = vftblptr(catchtype) class (not obj) */
614         mov     offbaseval(%rsi),%esi       /* %esi = baseval(xptr)               */
615         mov     offbaseval(%rdx),%r10d      /* %r10d = baseval(catchtype)         */
616         mov     offdiffval(%rdx),%edx       /* %edx = diffval(catchtype)          */
617 _crit_end1:
618         sub     %r10d,%esi                  /* %esi = baseval(xptr) - baseval(catchtype) */
619
620 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
621         add     $8,%rsp
622 #endif
623
624         cmp     %edx,%esi                   /* xptr is instanceof catchtype       */
625         ja      ex_table_cont
626                 
627 ex_handle_it:
628                 mov     ExHandlerPC(%rdi),xpc       /* xpc = exception handler pc     */
629
630         mov     0*8(%rsp),%rax              /* restore exception pointer      */
631         add     $(4*8),%rsp                 /* free stack frame               */
632
633         jmp             *xpc                        /* jump to the handler            */
634
635 ex_table_cont:
636         lea             ExEntrySize(%rdi),%rdi      /* next exception table entry     */
637         dec     %rcx                        /* decrement entry counter        */
638         test    %rcx,%rcx                   /* if (t0 > 0) next entry         */
639         jg              ex_table_loop
640                 
641 empty_table:
642         mov     0*8(%rsp),%rax              /* restore exception pointer      */
643         mov     1*8(%rsp),%r10              /* restore exception pc           */
644         mov     2*8(%rsp),%r11                          /* restore data segment pointer   */
645         add     $(4*8),%rsp
646         
647                 mov     %rax,%rcx                                       /* save exception pointer         */
648                                 
649 ex_already_cleared:             
650                 movl    IsSync(%r11),%eax                       /* %rax = SyncOffset              */
651                 test    %rax,%rax                                       /* if zero no monitorexit         */
652                 je              no_monitor_exit
653                 
654                 add     %rsp,%rax
655                 mov     -8(%rax),%rdi
656
657         sub     $(4*8),%rsp
658         mov     %rcx,0*8(%rsp)
659         mov     %r10,1*8(%rsp)
660         mov     %r11,2*8(%rsp)
661         
662                 call    builtin_monitorexit
663
664         mov     0*8(%rsp),%rcx
665         mov     1*8(%rsp),%r10
666         mov     2*8(%rsp),%r11
667         add     $(4*8),%rsp
668                 
669 no_monitor_exit:
670                 mov             FrameSize(%r11),%eax        /* %eax = frame size              */
671                 add             %rax,%rsp                   /* unwind stack                   */
672                 mov             %rsp,%rax                   /* %rax = pointer to save area    */
673
674                 mov             IntSave(%r11),%edx          /* %edx = saved int register count*/
675         test    %edx,%edx
676         je              noint
677         
678                 cmp     $1,%edx
679                 je              int1
680                 cmp             $2,%edx
681                 je              int2
682                 cmp             $3,%edx
683                 je              int3
684                 cmp             $4,%edx
685                 je              int4
686                 cmp             $5,%edx
687                 je              int5
688         
689         mov     -48(%rax),%rbx
690 int5:   
691         mov     -40(%rax),%rbp
692 int4:   
693         mov     -32(%rax),%r12
694 int3:   
695         mov     -24(%rax),%r13
696 int2:   
697                 mov     -16(%rax),%r14
698 int1:   
699                 mov     -8(%rax),%r15
700
701                 shl             $3,%edx                     /* multiply by 8 bytes            */
702                 sub     %rdx,%rax
703                 
704 noint:
705                 mov     FltSave(%r11),%edx          /* %edx = saved flt register count*/
706                 test    %edx,%edx
707                 je      noflt
708
709         cmpl    $1,%edx
710         je      flt1
711         cmpl    $2,%edx
712         je      flt2
713         cmpl    $3,%edx
714         je      flt3
715         cmpl    $4,%edx
716         je      flt4
717         cmpl    $5,%edx
718         je      flt5
719         cmpl    $6,%edx
720         je      flt7
721         cmpl    $7,%edx
722         je      flt7
723
724         movq    -64(%rax),%xmm8
725 flt7:   
726         movq    -56(%rax),%xmm9
727 flt6:   
728         movq    -48(%rax),%xmm10
729 flt5:   
730         movq    -40(%rax),%xmm11
731 flt4:   
732         movq    -32(%rax),%xmm12
733 flt3:   
734         movq    -24(%rax),%xmm13
735 flt2:   
736         movq    -16(%rax),%xmm14
737 flt1:   
738         movq    -8(%rax),%xmm15
739                 
740 noflt:                                  
741                 pop     %r10                                            /* the new xpc is return address  */
742                 sub     $3,%r10                     /* subtract 3 bytes for call      */
743
744         sub     $(2*8),%rsp
745         mov     %rcx,0*8(%rsp)
746         mov     %r10,1*8(%rsp)
747
748         mov     %r10,%rdi
749         call    codegen_findmethod          /* get the new data segment ptr   */
750         mov     %rax,%r11
751         
752         mov     0*8(%rsp),%rcx
753         mov     1*8(%rsp),%r10
754         add     $(2*8),%rsp
755
756         mov     %rcx,%rax                                       /* restore saved exception pointer*/
757
758         sub     $(4*8),%rsp
759                                         
760         mov     %rax,0*8(%rsp)              /* save exception pointer         */
761         mov     %r10,1*8(%rsp)              /* save exception pc              */
762                 mov     %r11,2*8(%rsp)                          /* save data segment pointer      */
763                 
764                 jmp             ex_stack_loop
765
766
767 /* asm_check_clinit ************************************************************
768
769    DOCUMENT ME!!!
770
771    Stack layout:
772
773         32  ra      ; return address of patched call in java machine code
774         24  xmcode  ; additional machine code (only for i386 and x86_64)
775         16  mcode   ; machine code to patch back in
776         8   class   ; pointer to class
777         0   sp      ; stack pointer of java stack frame + return address
778
779 *******************************************************************************/
780
781 asm_check_clinit:
782         mov     8(%rsp),itmp1
783         mov             offclassinit(itmp1),itmp1l  /* get initialized flag (int)         */
784         test    itmp1,itmp1
785         jnz             L_is_initialized
786
787         sub             $(15*8),%rsp                /* keep stack 16-byte aligned         */
788
789         mov             %rdi,0*8(%rsp)              /* save argument registers            */
790         mov             %rsi,1*8(%rsp)
791         mov             %rdx,2*8(%rsp)
792         mov             %rcx,3*8(%rsp)
793         mov             %r8,4*8(%rsp)
794         mov             %r9,5*8(%rsp)
795
796         movq    %xmm0,6*8(%rsp)             /* maybe cacao does not use all 8     */
797         movq    %xmm1,7*8(%rsp)             /* argument register, but who knows   */
798         movq    %xmm2,8*8(%rsp)
799         movq    %xmm3,9*8(%rsp)
800         movq    %xmm4,10*8(%rsp)
801         movq    %xmm5,11*8(%rsp)
802         movq    %xmm6,12*8(%rsp)
803         movq    %xmm7,13*8(%rsp)
804
805         mov             8+15*8(%rsp),%rdi           /* pass classinfo pointer             */
806         call    class_init                  /* call class_init function           */
807         
808     mov     0*8(%rsp),%rdi              /* restore argument registers         */
809     mov     1*8(%rsp),%rsi
810     mov     2*8(%rsp),%rdx
811     mov     3*8(%rsp),%rcx
812     mov     4*8(%rsp),%r8
813     mov     5*8(%rsp),%r9
814
815         movq    6*8(%rsp),%xmm0
816         movq    7*8(%rsp),%xmm1
817         movq    8*8(%rsp),%xmm2
818         movq    9*8(%rsp),%xmm3
819         movq    10*8(%rsp),%xmm4
820         movq    11*8(%rsp),%xmm5
821         movq    12*8(%rsp),%xmm6
822         movq    13*8(%rsp),%xmm7
823
824         add             $(15*8),%rsp
825
826         test    v0,v0                       /* we had an exception                */
827         je      L_initializererror
828                                 
829 L_is_initialized:
830         mov     32(%rsp),itmp1              /* get return address                 */
831         sub     $5,itmp1                    /* remove size of `call rel32'        */
832
833         mov     24(%rsp),itmp2              /* get xmcode machine code            */
834         movb    itmp2b,(itmp1)              /* patch back in 1 byte               */
835         mov     16(%rsp),itmp2              /* get mcode machine code             */
836         movl    itmp2l,1(itmp1)             /* patch back in 4 bytes              */
837
838         add     $(5*8),%rsp                 /* remove stub stack frame incl. ra   */
839
840         jmp     *itmp1                      /* jump to patched code an execute it */
841
842 L_initializererror:
843         add     $(4*8),%rsp                 /* remove stub stack frame            */
844
845 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
846         call    builtin_asm_get_exceptionptrptr
847         mov     %rax,itmp2
848         mov     (itmp2),xptr                /* get the exception pointer          */
849         movl    $0,(itmp2)                  /* clear the exception pointer        */
850 #else
851         lea     _exceptionptr,itmp2
852         mov     (itmp2),xptr                /* get the exception pointer          */
853         movl    $0,(itmp2)                  /* clear the exception pointer        */
854 #endif
855
856         pop     xpc                         /* delete return address              */
857         sub     $5,xpc                      /* faulting address is ra - 5         */
858
859         jmp     asm_handle_exception
860                 
861
862 /********************* function asm_builtin_monitorenter ***********************
863 *                                                                              *
864 *   Does null check and calls monitorenter or throws an exception              *
865 *                                                                              *
866 *******************************************************************************/
867
868 asm_builtin_monitorenter:
869         test    %rdi,%rdi
870         je      nb_monitorenter             /* if (null) throw exception          */
871         jmp     builtin_monitorenter        /* else call builtin_monitorenter     */
872
873 nb_monitorenter:
874         call    new_nullpointerexception
875     pop     %r10                        /* delete return address              */
876     sub     $3,%r10                     /* faulting address is return adress - 3 */
877     jmp     asm_handle_exception
878                 
879
880 /********************* function asm_builtin_monitorexit ************************
881 *                                                                              *
882 *   Does null check and calls monitorexit or throws an exception               *
883 *                                                                              *
884 *******************************************************************************/
885
886 asm_builtin_monitorexit:
887         test    %rdi,%rdi
888         je      nb_monitorexit              /* if (null) throw exception          */
889         jmp     builtin_monitorexit         /* else call builtin_monitorenter     */
890
891 nb_monitorexit:
892         call    new_nullpointerexception
893     pop     %r10                        /* delete return address              */
894     sub     $3,%r10                     /* faulting address is return adress - 3 */
895     jmp     asm_handle_exception
896
897
898 /********************* function asm_builtin_x2x ********************************
899 *                                                                              *
900 *   Wrapper functions for float to int corner cases                            *
901 *                                                                              *
902 *******************************************************************************/
903
904 asm_builtin_f2i:
905         sub     $(14*8),%rsp
906         
907         mov     %rdi,0*8(%rsp)
908         mov     %rsi,1*8(%rsp)
909         mov     %rdx,2*8(%rsp)
910         mov     %rcx,3*8(%rsp)
911         mov     %r8,4*8(%rsp)
912         mov     %r9,5*8(%rsp)
913         
914         movq    %xmm0,6*8(%rsp)
915         movq    %xmm1,7*8(%rsp)
916         movq    %xmm2,8*8(%rsp)
917         movq    %xmm3,9*8(%rsp)
918         movq    %xmm4,10*8(%rsp)
919         movq    %xmm5,11*8(%rsp)
920         movq    %xmm6,12*8(%rsp)
921         movq    %xmm7,13*8(%rsp)
922         
923         movq    %xmm8,%xmm0
924         call    builtin_f2i
925         
926         mov     0*8(%rsp),%rdi
927         mov     1*8(%rsp),%rsi
928         mov     2*8(%rsp),%rdx
929         mov     3*8(%rsp),%rcx
930         mov     4*8(%rsp),%r8
931         mov     5*8(%rsp),%r9
932         
933         movq    6*8(%rsp),%xmm0
934         movq    7*8(%rsp),%xmm1
935         movq    8*8(%rsp),%xmm2
936         movq    9*8(%rsp),%xmm3
937         movq    10*8(%rsp),%xmm4
938         movq    11*8(%rsp),%xmm5
939         movq    12*8(%rsp),%xmm6
940         movq    13*8(%rsp),%xmm7
941         
942         add     $(14*8),%rsp
943         ret
944
945
946 asm_builtin_f2l:
947         sub     $(14*8),%rsp
948         
949         mov     %rdi,0*8(%rsp)
950         mov     %rsi,1*8(%rsp)
951         mov     %rdx,2*8(%rsp)
952         mov     %rcx,3*8(%rsp)
953         mov     %r8,4*8(%rsp)
954         mov     %r9,5*8(%rsp)
955         
956         movq    %xmm0,6*8(%rsp)
957         movq    %xmm1,7*8(%rsp)
958         movq    %xmm2,8*8(%rsp)
959         movq    %xmm3,9*8(%rsp)
960         movq    %xmm4,10*8(%rsp)
961         movq    %xmm5,11*8(%rsp)
962         movq    %xmm6,12*8(%rsp)
963         movq    %xmm7,13*8(%rsp)
964         
965         movq    %xmm8,%xmm0
966         call    builtin_f2l
967         
968         mov     0*8(%rsp),%rdi
969         mov     1*8(%rsp),%rsi
970         mov     2*8(%rsp),%rdx
971         mov     3*8(%rsp),%rcx
972         mov     4*8(%rsp),%r8
973         mov     5*8(%rsp),%r9
974         
975         movq    6*8(%rsp),%xmm0
976         movq    7*8(%rsp),%xmm1
977         movq    8*8(%rsp),%xmm2
978         movq    9*8(%rsp),%xmm3
979         movq    10*8(%rsp),%xmm4
980         movq    11*8(%rsp),%xmm5
981         movq    12*8(%rsp),%xmm6
982         movq    13*8(%rsp),%xmm7
983         
984         add     $(14*8),%rsp
985         ret
986
987
988 asm_builtin_d2i:
989         sub     $(14*8),%rsp
990         
991         mov     %rdi,0*8(%rsp)
992         mov     %rsi,1*8(%rsp)
993         mov     %rdx,2*8(%rsp)
994         mov     %rcx,3*8(%rsp)
995         mov     %r8,4*8(%rsp)
996         mov     %r9,5*8(%rsp)
997         
998         movq    %xmm0,6*8(%rsp)
999         movq    %xmm1,7*8(%rsp)
1000         movq    %xmm2,8*8(%rsp)
1001         movq    %xmm3,9*8(%rsp)
1002         movq    %xmm4,10*8(%rsp)
1003         movq    %xmm5,11*8(%rsp)
1004         movq    %xmm6,12*8(%rsp)
1005         movq    %xmm7,13*8(%rsp)
1006         
1007         movq    %xmm8,%xmm0
1008         call    builtin_d2i
1009         
1010         mov     0*8(%rsp),%rdi
1011         mov     1*8(%rsp),%rsi
1012         mov     2*8(%rsp),%rdx
1013         mov     3*8(%rsp),%rcx
1014         mov     4*8(%rsp),%r8
1015         mov     5*8(%rsp),%r9
1016         
1017         movq    6*8(%rsp),%xmm0
1018         movq    7*8(%rsp),%xmm1
1019         movq    8*8(%rsp),%xmm2
1020         movq    9*8(%rsp),%xmm3
1021         movq    10*8(%rsp),%xmm4
1022         movq    11*8(%rsp),%xmm5
1023         movq    12*8(%rsp),%xmm6
1024         movq    13*8(%rsp),%xmm7
1025         
1026         add     $(14*8),%rsp
1027         ret
1028
1029
1030 asm_builtin_d2l:
1031         sub     $(14*8),%rsp
1032         
1033         mov     %rdi,0*8(%rsp)
1034         mov     %rsi,1*8(%rsp)
1035         mov     %rdx,2*8(%rsp)
1036         mov     %rcx,3*8(%rsp)
1037         mov     %r8,4*8(%rsp)
1038         mov     %r9,5*8(%rsp)
1039         
1040         movq    %xmm0,6*8(%rsp)
1041         movq    %xmm1,7*8(%rsp)
1042         movq    %xmm2,8*8(%rsp)
1043         movq    %xmm3,9*8(%rsp)
1044         movq    %xmm4,10*8(%rsp)
1045         movq    %xmm5,11*8(%rsp)
1046         movq    %xmm6,12*8(%rsp)
1047         movq    %xmm7,13*8(%rsp)
1048         
1049         movq    %xmm8,%xmm0
1050         call    builtin_d2l
1051         
1052         mov     0*8(%rsp),%rdi
1053         mov     1*8(%rsp),%rsi
1054         mov     2*8(%rsp),%rdx
1055         mov     3*8(%rsp),%rcx
1056         mov     4*8(%rsp),%r8
1057         mov     5*8(%rsp),%r9
1058         
1059         movq    6*8(%rsp),%xmm0
1060         movq    7*8(%rsp),%xmm1
1061         movq    8*8(%rsp),%xmm2
1062         movq    9*8(%rsp),%xmm3
1063         movq    10*8(%rsp),%xmm4
1064         movq    11*8(%rsp),%xmm5
1065         movq    12*8(%rsp),%xmm6
1066         movq    13*8(%rsp),%xmm7
1067         
1068         add     $(14*8),%rsp
1069         ret
1070
1071
1072 /******************* function asm_builtin_checkarraycast ***********************
1073 *                                                                              *
1074 *   Does the cast check and eventually throws an exception                     *
1075 *                                                                              *
1076 *******************************************************************************/
1077
1078 asm_builtin_checkarraycast:
1079         sub     $24,%rsp                /* keep stack 16-byte aligned         */
1080         mov     %rdi,(%rsp)             /* save object pointer                */
1081         call    builtin_checkarraycast  /* builtin_checkarraycast             */
1082         test    %rax,%rax               /* if (false) throw exception         */
1083         je      nb_carray_throw
1084         mov     (%rsp),%rax             /* return object pointer              */
1085         add     $24,%rsp                /* free stack space                   */
1086         ret
1087
1088 nb_carray_throw:
1089         call    new_classcastexception
1090         add     $24,%rsp
1091         pop     %r10                    /* delete return address              */
1092         sub     $3,%r10                 /* faulting address is return adress - 3 */
1093         jmp     asm_handle_exception
1094
1095                 
1096 /******************* function asm_builtin_aastore ******************************
1097 *                                                                              *
1098 *   Does the cast check and eventually throws an exception                     *
1099 *                                                                              *
1100 *******************************************************************************/
1101
1102 asm_builtin_aastore:
1103         sub     $(3*8),%rsp             /* allocate stack space               */
1104         test    %rdi,%rdi               /* if null pointer throw exception    */
1105         je      nb_aastore_null
1106
1107         movl    offarraysize(%rdi),%eax /* load size                          */
1108         cmpl    %eax,%esi                               /* do bound check                     */
1109         jae     nb_aastore_bound                /* if out of bounds throw exception   */
1110
1111         shl     $3,%rsi                                 /* index * 8                          */
1112         mov     %rdi,%r10
1113         add     %rsi,%r10                               /* add index * 8 to arrayref          */
1114                 
1115         mov     %r10,(%rsp)                     /* save store position                */
1116         mov     %rdx,8(%rsp)            /* save object                        */
1117         
1118         mov     %rdx,%rsi               /* object is second argument          */
1119         call    builtin_canstore                /* builtin_canstore(arrayref,object)  */
1120         test    %rax,%rax                               /* if (false) throw exception         */
1121         je      nb_aastore_throw
1122
1123         mov     (%rsp),%r10             /* restore store position             */
1124         mov     8(%rsp),%rdx            /* restore object                     */
1125         mov     %rdx,offobjarrdata(%r10)/* store objectptr in array           */
1126         add     $(3*8),%rsp             /* free stack space                   */
1127         ret
1128
1129 nb_aastore_null:
1130                 call    new_nullpointerexception
1131         add     $24,%rsp
1132         pop     %r10                                    /* delete return address              */
1133         sub     $3,%r10                                 /* faulting address is return adress - 3 */
1134         jmp     asm_handle_exception
1135
1136 nb_aastore_bound:
1137                 mov     %rsi,%rdi               /* move index into a0                 */
1138                 call    new_arrayindexoutofboundsexception
1139         add     $24,%rsp
1140         pop     %r10                                    /* delete return address              */
1141         sub     $3,%r10                                 /* faulting address is return adress - 3 */
1142         jmp     asm_handle_exception
1143                 
1144 nb_aastore_throw:
1145                 call    new_arraystoreexception
1146         add     $24,%rsp
1147         pop     %r10                                    /* delete return address              */
1148         sub     $3,%r10                                 /* faulting address is return adress - 3 */
1149         jmp             asm_handle_exception
1150
1151                 
1152 /******************* function asm_initialize_thread_stack **********************
1153 *                                                                              *
1154 * initialized a thread stack                                                   *
1155 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1156 *                                                                              *
1157 *******************************************************************************/
1158
1159 asm_initialize_thread_stack:
1160         sub     $(7*8),%rsi
1161
1162         xor     %r10,%r10
1163         mov     %r10,0*8(%rsi)
1164         mov     %r10,1*8(%rsi)
1165         mov     %r10,2*8(%rsi)
1166         mov     %r10,3*8(%rsi)
1167         mov     %r10,4*8(%rsi)
1168         mov     %r10,5*8(%rsi)
1169
1170         mov     %rdi,6*8(%rsi)          /* save (u1*) (func)                  */
1171         mov     %rsi,%rax               /* return restorepoint in %rax        */
1172         ret
1173
1174
1175 /******************* function asm_perform_threadswitch *************************
1176 *                                                                              *
1177 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
1178 *                                                                              *
1179 *   performs a threadswitch                                                    *
1180 *                                                                              *
1181 *******************************************************************************/
1182
1183 asm_perform_threadswitch:
1184         sub     $(7*8),%rsp             /* allocate stack frame               */
1185
1186         mov     %rbx,0*8(%rsp)
1187         mov     %rbp,1*8(%rsp)
1188         mov     %r12,2*8(%rsp)
1189         mov     %r13,3*8(%rsp)
1190         mov     %r14,4*8(%rsp)
1191         mov     %r15,5*8(%rsp)
1192
1193         mov     7*8(%rsp),%rax                  /* save current return address        */
1194         mov     %rax,6*8(%rsp)
1195
1196         mov     %rsp,(%rdi)                     /* first argument **from              */
1197         mov     %rsp,(%rdx)                     /* third argument **stackTop          */
1198
1199         mov     (%rsi),%rsp                     /* load new stack pointer             */
1200
1201         mov     0*8(%rsp),%rbx
1202         mov     1*8(%rsp),%rbp
1203         mov     2*8(%rsp),%r12
1204         mov     3*8(%rsp),%r13
1205         mov     4*8(%rsp),%r14
1206         mov     5*8(%rsp),%r15
1207
1208         mov     6*8(%rsp),%rax          /* restore return address             */
1209         add     $(7*8),%rsp             /* free stack frame                   */
1210         mov     %rax,(%rsp)
1211         ret
1212                 
1213
1214 /********************* function asm_switchstackandcall *************************
1215 *                                                                              *
1216 *  int asm_switchstackandcall (void *stack, void *func, void **stacktopsave,   *
1217 *                                      void *p);                                       *
1218 *                                                                              *
1219 *   Switches to a new stack, calls a function and switches back.               *
1220 *       a0 (%rdi)     new stack pointer                                        *
1221 *       a1 (%rsi)     function pointer                                         *
1222 *               a2 (%rdx)     pointer to variable where stack top should be stored     *
1223 *       a3 (%rcx)     pointer to user data, is passed to the function          *
1224 *                                                                              *
1225 *******************************************************************************/
1226
1227 asm_switchstackandcall:
1228         sub     $(1*8),%rsp             /* keep stack 16-byte aligned         */
1229         sub     $16,%rdi                                /* allocate new stack                 */
1230
1231         mov     8(%rsp),%rax                    /* save return address on new stack   */
1232         mov     %rax,(%rdi)
1233         mov     %rsp,8(%rdi)                    /* save old stack pointer on new stack*/
1234         mov     %rsp,(%rdx)                             /* save old stack pointer to variable */
1235
1236         mov     %rdi,%rsp                               /* switch to new stack                */
1237
1238         mov     %rcx,%rdi                       /* pass pointer                       */
1239         call    *%rsi                                   /* and call function                  */
1240
1241         mov     (%rsp),%r10                             /* load return address                */
1242         mov     8(%rsp),%rsp                    /* switch to old stack                */
1243         add     $(1*8),%rsp             /* free stack space                   */
1244         mov     %r10,(%rsp)             /* write return adress                */
1245         ret
1246
1247
1248 asm_getclassvalues_atomic:
1249 _crit_restart2:
1250 _crit_begin2:
1251         movl    offbaseval(a0),itmp1l
1252         movl    offdiffval(a0),itmp2l
1253         movl    offbaseval(a1),itmp3l
1254 _crit_end2:
1255         movl    itmp1l,offcast_super_baseval(a2)
1256         movl    itmp2l,offcast_super_diffval(a2)
1257         movl    itmp3l,offcast_sub_baseval(a2)
1258         ret
1259
1260         .data
1261                 
1262 asm_criticalsections:
1263 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1264         .quad   _crit_begin1
1265         .quad   _crit_end1
1266         .quad   _crit_restart1
1267         .quad   _crit_begin2
1268         .quad   _crit_end2
1269         .quad   _crit_restart2
1270 #endif
1271         .quad 0
1272
1273                                 
1274 /*
1275  * These are local overrides for various environment variables in Emacs.
1276  * Please do not remove this and leave it at the end of the file, where
1277  * Emacs will automagically detect them.
1278  * ---------------------------------------------------------------------
1279  * Local variables:
1280  * mode: asm
1281  * indent-tabs-mode: t
1282  * c-basic-offset: 4
1283  * tab-width: 4
1284  * End:
1285  */