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