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