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