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