Again a libc-movaps bugfix. Arghhh!
[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 2414 2005-04-29 18:55:09Z 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      32   return address
850          24   pointer to virtual java_objectheader
851      16   machine code (which is patched back later)
852       8   unresolved class/method/field reference
853       0   pointer to patcher function
854
855 *******************************************************************************/
856
857 asm_wrapper_patcher:
858         sub     $(17*8),%rsp                /* stack frame (16-byte aligned)      */
859
860         SAVE_ARGUMENT_REGISTERS
861         SAVE_TEMPORARY_REGISTERS
862
863         mov     itmp1,15*8(%rsp)            /* save itmp1 and itmp2               */
864         mov     itmp2,16*8(%rsp)            /* can be used by some instructions   */
865
866         mov     %rsp,a0                     /* pass stack pointer                 */
867         add     $(18*8),a0                  /* skip patcher function pointer      */
868         mov     17*8(%rsp),itmp3            /* get function pointer               */
869         call    *itmp3                      /* call the patcher function          */
870         mov     v0,itmp3                    /* save return value                  */
871
872         RESTORE_ARGUMENT_REGISTERS
873         RESTORE_TEMPORARY_REGISTERS
874
875         mov     15*8(%rsp),itmp1            /* restore itmp1 and itmp2            */
876         mov     16*8(%rsp),itmp2            /* can be used by some instructions   */
877
878         add     $((4+17)*8),%rsp            /* remove stack frame, keep ra        */
879
880         test    itmp3,itmp3                 /* exception thrown?                  */
881         jz      L_asm_wrapper_patcher_exception
882         ret                                 /* call new patched code              */
883
884 L_asm_wrapper_patcher_exception:
885         /*stack bottom is xpc and it is directly below the last java stackframe*/
886         push $0
887         push $0
888         push $0 /*padding*/
889         call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
890
891 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
892         call    builtin_asm_get_exceptionptrptr
893         mov     v0,itmp2
894 #else
895         lea     _exceptionptr,itmp2
896 #endif
897         mov     (itmp2),a0                  /* get the exception pointer          */
898         movl    $0,(itmp2)                  /* clear exception pointer            */
899         call    helper_fillin_stacktrace
900
901         mov     v0,xptr
902
903         call    asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
904         add     $8,%rsp
905
906         pop     xpc                         /* get and remove return address      */
907         jmp     asm_handle_exception
908
909
910 /* asm_builtin_x2x *************************************************************
911 *                                                                              *
912 *   Wrapper functions for float to int corner cases                            *
913 *                                                                              *
914 *******************************************************************************/
915
916 asm_builtin_f2i:
917         sub     $(14*8),%rsp
918         
919         SAVE_ARGUMENT_REGISTERS
920         
921         movq    %xmm8,%xmm0
922         call    builtin_f2i
923         
924         RESTORE_ARGUMENT_REGISTERS
925         
926         add     $(14*8),%rsp
927         ret
928
929
930 asm_builtin_f2l:
931         sub     $(14*8),%rsp
932         
933         SAVE_ARGUMENT_REGISTERS
934         
935         movq    %xmm8,%xmm0
936         call    builtin_f2l
937         
938         RESTORE_ARGUMENT_REGISTERS
939         
940         add     $(14*8),%rsp
941         ret
942
943
944 asm_builtin_d2i:
945         sub     $(14*8),%rsp
946         
947         SAVE_ARGUMENT_REGISTERS
948         
949         movq    %xmm8,%xmm0
950         call    builtin_d2i
951         
952         RESTORE_ARGUMENT_REGISTERS
953         
954         add     $(14*8),%rsp
955         ret
956
957
958 asm_builtin_d2l:
959         sub     $(14*8),%rsp
960         
961         SAVE_ARGUMENT_REGISTERS
962         
963         movq    %xmm8,%xmm0
964         call    builtin_d2l
965         
966         RESTORE_ARGUMENT_REGISTERS
967         
968         add     $(14*8),%rsp
969         ret
970
971
972 /* asm_builtin_checkarraycast **************************************************
973
974    Does the cast check and eventually throws an exception.
975
976 *******************************************************************************/
977
978 asm_builtin_checkarraycast:
979         sub     $24,%rsp                    /* keep stack 16-byte aligned         */
980         mov     %rdi,(%rsp)                 /* save object pointer                */
981         call    builtin_checkarraycast      /* builtin_checkarraycast             */
982         test    %rax,%rax                   /* if (false) throw exception         */
983         je      nb_carray_throw
984         mov     (%rsp),%rax                 /* return object pointer              */
985         add     $24,%rsp                    /* free stack space                   */
986         ret
987
988 nb_carray_throw:
989         /*call    new_classcastexception*/
990         add     $24,%rsp
991         pop     xpc                        /* delete return address              */
992         sub     $3,xpc                     /* faulting address is ra - 3         */
993         mov     string_java_lang_ClassCastException,xptr
994         jmp     asm_throw_and_handle_exception
995
996                 
997 /* asm_builtin_aastore *********************************************************
998
999    Checks if the object can be stored in the given array and stores the
1000    address if it's possible. This function can also throw some exceptions.
1001
1002 *******************************************************************************/
1003
1004 asm_builtin_aastore:
1005         sub     $(3*8),%rsp             /* allocate stack space                   */
1006         test    %rdi,%rdi               /* if null pointer throw exception        */
1007         je      nb_aastore_null
1008
1009         movl    offarraysize(%rdi),%eax /* load size                              */
1010         cmpl    %eax,%esi               /* do bound check                         */
1011         jae     nb_aastore_bound        /* if out of bounds throw exception       */
1012
1013         shl     $3,%rsi                 /* index * 8                              */
1014         mov     %rdi,%r10
1015         add     %rsi,%r10               /* add index * 8 to arrayref              */
1016
1017         mov     %r10,(%rsp)             /* save store position                    */
1018         mov     %rdx,8(%rsp)            /* save object                            */
1019
1020         mov     %rdx,%rsi               /* object is second argument              */
1021         call    builtin_canstore        /* builtin_canstore(arrayref,object)      */
1022         test    %rax,%rax               /* if (false) throw exception             */
1023         je      nb_aastore_throw
1024
1025         mov     (%rsp),%r10             /* restore store position                 */
1026         mov     8(%rsp),%rdx            /* restore object                         */
1027         mov     %rdx,offobjarrdata(%r10)/* store objectptr in array               */
1028         add     $(3*8),%rsp             /* free stack space                       */
1029         ret
1030
1031 nb_aastore_null:
1032         add     $24,%rsp
1033         pop     xpc                    /* delete return address from stack       */
1034         sub     $3,xpc                 /* faulting address is return adress - 3  */
1035         mov     string_java_lang_NullPointerException,xptr
1036         jmp    asm_throw_and_handle_exception
1037
1038 nb_aastore_bound:
1039         add     $24,%rsp
1040         push    $0 /*directly below return address*/
1041         push    $0 /*internal*/
1042         push    $0 /*padding*/
1043         mov     %rsi,itmp1
1044         
1045         call    asm_prepare_native_stackinfo
1046
1047         mov     itmp1,%rdi               /* move index into a0                     */
1048         call    new_arrayindexoutofboundsexception
1049
1050         call    asm_remove_native_stackinfo
1051
1052         pop     xpc                    /* just remove one quadword                  */
1053         pop     xpc                    /* delete return address                  */
1054         sub     $3,xpc                 /* faulting address is return adress - 3  */
1055         jmp     asm_handle_exception
1056                 
1057 nb_aastore_throw:
1058         /*call    new_arraystoreexception*/
1059         add     $24,%rsp
1060         pop     xpc                    /* delete return address                  */
1061         sub     $3,xpc                 /* faulting address is return adress - 3  */
1062         mov     string_java_lang_ArrayStoreException,xptr
1063         jmp     asm_throw_and_handle_exception
1064
1065                 
1066 /******************* function asm_initialize_thread_stack **********************
1067 *                                                                              *
1068 * initialized a thread stack                                                   *
1069 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1070 *                                                                              *
1071 *******************************************************************************/
1072
1073 asm_initialize_thread_stack:
1074         sub     $(7*8),%rsi
1075
1076         xor     %r10,%r10
1077         mov     %r10,0*8(%rsi)
1078         mov     %r10,1*8(%rsi)
1079         mov     %r10,2*8(%rsi)
1080         mov     %r10,3*8(%rsi)
1081         mov     %r10,4*8(%rsi)
1082         mov     %r10,5*8(%rsi)
1083
1084         mov     %rdi,6*8(%rsi)          /* save (u1*) (func)                  */
1085         mov     %rsi,%rax               /* return restorepoint in %rax        */
1086         ret
1087
1088
1089 /******************* function asm_perform_threadswitch *************************
1090 *                                                                              *
1091 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
1092 *                                                                              *
1093 *   performs a threadswitch                                                    *
1094 *                                                                              *
1095 *******************************************************************************/
1096
1097 asm_perform_threadswitch:
1098         sub     $(7*8),%rsp             /* allocate stack frame               */
1099
1100         mov     %rbx,0*8(%rsp)
1101         mov     %rbp,1*8(%rsp)
1102         mov     %r12,2*8(%rsp)
1103         mov     %r13,3*8(%rsp)
1104         mov     %r14,4*8(%rsp)
1105         mov     %r15,5*8(%rsp)
1106
1107         mov     7*8(%rsp),%rax                  /* save current return address        */
1108         mov     %rax,6*8(%rsp)
1109
1110         mov     %rsp,(%rdi)                     /* first argument **from              */
1111         mov     %rsp,(%rdx)                     /* third argument **stackTop          */
1112
1113         mov     (%rsi),%rsp                     /* load new stack pointer             */
1114
1115         mov     0*8(%rsp),%rbx
1116         mov     1*8(%rsp),%rbp
1117         mov     2*8(%rsp),%r12
1118         mov     3*8(%rsp),%r13
1119         mov     4*8(%rsp),%r14
1120         mov     5*8(%rsp),%r15
1121
1122         mov     6*8(%rsp),%rax          /* restore return address             */
1123         add     $(7*8),%rsp             /* free stack frame                   */
1124         mov     %rax,(%rsp)
1125         ret
1126                 
1127
1128 /********************* function asm_switchstackandcall *************************
1129 *                                                                              *
1130 *  int asm_switchstackandcall (void *stack, void *func, void **stacktopsave,   *
1131 *                                      void *p);                                       *
1132 *                                                                              *
1133 *   Switches to a new stack, calls a function and switches back.               *
1134 *       a0 (%rdi)     new stack pointer                                        *
1135 *       a1 (%rsi)     function pointer                                         *
1136 *               a2 (%rdx)     pointer to variable where stack top should be stored     *
1137 *       a3 (%rcx)     pointer to user data, is passed to the function          *
1138 *                                                                              *
1139 *******************************************************************************/
1140
1141 asm_switchstackandcall:
1142         sub     $(1*8),%rsp             /* keep stack 16-byte aligned         */
1143         sub     $16,%rdi                                /* allocate new stack                 */
1144
1145         mov     8(%rsp),%rax                    /* save return address on new stack   */
1146         mov     %rax,(%rdi)
1147         mov     %rsp,8(%rdi)                    /* save old stack pointer on new stack*/
1148         mov     %rsp,(%rdx)                             /* save old stack pointer to variable */
1149
1150         mov     %rdi,%rsp                               /* switch to new stack                */
1151
1152         mov     %rcx,%rdi                       /* pass pointer                       */
1153         call    *%rsi                                   /* and call function                  */
1154
1155         mov     (%rsp),%r10                             /* load return address                */
1156         mov     8(%rsp),%rsp                    /* switch to old stack                */
1157         add     $(1*8),%rsp             /* free stack space                   */
1158         mov     %r10,(%rsp)             /* write return adress                */
1159         ret
1160
1161
1162
1163
1164 /************************ function asm_prepare_native_stackinfo ****************************
1165 *                                                                                          *
1166 *    creates a stackfame for the begin of a native function (either builtin or not )       *
1167 *    expected stack at begin of function                                                   *
1168 *                                        ....                                              *
1169 *                   address of the jit call which invokes the native                       *
1170 *                   begin address of stack frame of the java method                        *
1171 *                   method pointer or 0 (for built ins)                                    *
1172 *                   padding for stackframesize 16*n+8                                      *
1173 *                   return address                                                         *
1174 *                                                                                          *
1175 *    at end of function:                                                                   *
1176 *                                          ...                                             *
1177 *                   address of the jit call which invokes the native                       *
1178 *                   begin address of stack frame of the java method                        *
1179 *                   method pointer or 0 (for built ins)                                    *
1180 *                   address of thread specific top of native list                          *
1181 *                   old value of thread specific head                                      *
1182 *                   padding for stackframesize 16*n+8)                                     *
1183 *                   return address                                                         *
1184 *                                                                                          *
1185 *                                        ....                                              *
1186 * This thing is less efficient than the original #define (callerside)                      *
1187 * destroyes REG_ITMP2, keeps REG_ITMP1                                                     *
1188 ********************************************************************************************/
1189
1190
1191 asm_prepare_native_stackinfo:
1192         sub $16,%rsp  /*space for the 2 new pointers*/
1193         mov 16(%rsp),itmp2
1194         mov itmp2,(%rsp)
1195         push itmp1
1196         call builtin_asm_get_stackframeinfo
1197
1198         mov itmp1, 32(%rsp)
1199         mov (itmp1),itmp2
1200         mov itmp2,24(%rsp)
1201         mov %rsp,itmp2
1202         add $24,itmp2
1203         mov itmp2,(itmp1)
1204         pop itmp1
1205         ret
1206
1207                 
1208
1209 /************************ function asm_remove _native_stackinfo *******************************************
1210 *                                                                                                         *
1211 *    removes a stackfame for the begin of a native function (either builtin or not)                       *
1212 *    expected stack at begin of function                                                                  *
1213 *                   address of the jit call which invokes the native                                      *
1214 *                   begin address of stack frame of the java method                                       *
1215 *                   method pointer or 0 (for built ins)                                                   *
1216 *                   address thread specific top of native list                                            *
1217 *                   old value of thread specific head                                                     *
1218 *                   padding                                                                               *
1219 *                   return address                                                                        *
1220 *                                                                                                         *
1221 *    at end of function:                                                                                  *
1222 *                             ....                                                                        *
1223 *                   return adresss of the jit call which invokes the native                               *
1224 *                   padding                                                                               *
1225 *                   return address                                                                        *
1226 *                                                                                                         *
1227 *                                                                                                         *
1228 *                                                                                                         *
1229 * This thing is less efficient than the original #define (callerside), uses ITMP2,uses ITMP3,keeps ITMP1  *
1230 ***********************************************************************************************************/
1231
1232 asm_remove_native_stackinfo:
1233         mov 16(%rsp),itmp2
1234         mov 24(%rsp),itmp3
1235         mov itmp2,(itmp3)
1236         pop itmp3
1237         add $32,%rsp
1238         push itmp3
1239         ret
1240
1241
1242
1243 asm_throw_and_handle_exception:
1244         push xpc /* the pushed XPC is directly below the java frame*/
1245         push $0 
1246         push $0
1247         push $0 /*padding*/
1248         call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1249         mov itmp1,%rdi
1250
1251         call new_exception
1252
1253         call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1254
1255         pop xpc
1256         pop xpc
1257
1258         jmp asm_handle_exception
1259         ret /*should never be reached */
1260
1261
1262 asm_throw_and_handle_hardware_arithmetic_exception:
1263
1264         push xpc
1265         push $0 /* the pushed XPC is directly below the java frame*/
1266         push $0
1267         push $0 /*padding*/
1268         call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1269
1270         mov string_java_lang_ArithmeticException_message,%rsi
1271         mov string_java_lang_ArithmeticException,%rdi
1272
1273         call new_exception_message
1274
1275         call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1276         pop xpc
1277         pop xpc
1278
1279         jmp asm_handle_exception
1280         ret /*should never be reached */
1281
1282
1283 asm_getclassvalues_atomic:
1284 _crit_restart2:
1285 _crit_begin2:
1286         movl    offbaseval(a0),itmp1l
1287         movl    offdiffval(a0),itmp2l
1288         movl    offbaseval(a1),itmp3l
1289 _crit_end2:
1290         movl    itmp1l,offcast_super_baseval(a2)
1291         movl    itmp2l,offcast_super_diffval(a2)
1292         movl    itmp3l,offcast_sub_baseval(a2)
1293         ret
1294
1295         .data
1296                 
1297 asm_criticalsections:
1298 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1299         .quad   _crit_begin1
1300         .quad   _crit_end1
1301         .quad   _crit_restart1
1302         .quad   _crit_begin2
1303         .quad   _crit_end2
1304         .quad   _crit_restart2
1305 #endif
1306         .quad 0
1307
1308                 
1309 /*
1310  * These are local overrides for various environment variables in Emacs.
1311  * Please do not remove this and leave it at the end of the file, where
1312  * Emacs will automagically detect them.
1313  * ---------------------------------------------------------------------
1314  * Local variables:
1315  * mode: asm
1316  * indent-tabs-mode: t
1317  * c-basic-offset: 4
1318  * tab-width: 4
1319  * End:
1320  */