First code patching functions.
[cacao.git] / src / vm / jit / i386 / asmpart.S
1 /* src/vm/jit/i386/asmpart.S - Java-C interface functions for i386
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    Changes: Joseph Wenninger
32
33    $Id: asmpart.S 2290 2005-04-12 21:57:56Z twisti $
34
35 */
36
37
38 #include "config.h"
39 #include "vm/jit/i386/offsets.h"
40 #include "vm/jit/i386/asmoffsets.h"
41
42
43 /* define it like the risc way */
44
45 #define v0       %eax
46
47 #define itmp1    %eax
48 #define itmp2    %ecx
49 #define itmp3    %edx
50
51 #define itmp1b   %al
52 #define itmp2b   %cl
53 #define itmp3b   %dl
54
55 #define xptr     itmp1
56 #define xpc      itmp2
57
58
59         .text
60
61
62 /********************* exported functions and variables ***********************/
63
64         .globl asm_calljavafunction
65         .globl asm_calljavafunction_int
66
67         .globl asm_calljavafunction2
68         .globl asm_calljavafunction2int
69         .globl asm_calljavafunction2long
70         .globl asm_calljavafunction2float
71         .globl asm_calljavafunction2double
72
73         .globl asm_call_jit_compiler
74         .globl asm_handle_builtin_exception
75         .globl asm_handle_nat_exception
76         .globl asm_handle_exception
77
78         .globl asm_check_clinit
79
80         .globl asm_patcher_builtin_new
81         .globl asm_patcher_invokestatic_special
82
83         .globl asm_builtin_checkarraycast
84         .globl asm_builtin_newarray
85         .globl asm_builtin_aastore
86
87 #if defined(USE_THREADS)
88         .globl asm_builtin_monitorenter
89         .globl asm_builtin_monitorexit
90 #endif
91
92         .globl asm_builtin_ldiv
93         .globl asm_builtin_lrem
94         .globl asm_builtin_f2i
95         .globl asm_builtin_f2l
96         .globl asm_builtin_d2i
97         .globl asm_builtin_d2l
98         .globl asm_builtin_arrayinstanceof
99         .globl asm_perform_threadswitch
100         .globl asm_initialize_thread_stack
101         .globl asm_switchstackandcall
102         .globl asm_getcallingmethod
103         .globl asm_criticalsections
104         .globl asm_getclassvalues_atomic
105
106         .globl asm_throw_and_handle_exception
107         .globl asm_throw_and_handle_hardware_arithmetic_exception
108
109         .globl asm_prepare_native_stackinfo
110         .globl asm_remove_native_stackinfo
111
112
113 /********************* function asm_calljavafunction ***************************
114 *                                                                              *
115 *   This function calls a Java-method (which possibly needs compilation)       *
116 *   with up to 4 address parameters.                                           *
117 *                                                                              *
118 *   This functions calls the JIT-compiler which eventually translates the      *
119 *   method into machine code.                                                  *
120 *                                                                              *
121 *   C-prototype:                                                               *
122 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
123 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
124 *                                                                              *
125 *******************************************************************************/
126
127 call_name:
128         .align  8
129
130         .long   0                         /* catch type all                       */
131         .long   calljava_xhandler         /* handler pc                           */
132         .long   calljava_xhandler         /* end pc                               */
133         .long   asm_calljavafunction      /* start pc                             */
134         .long   1                         /* extable size                         */
135         .long   0                         /* line number table  start             */
136         .long   0                         /* line number table  size              */
137         .long   0                         /* fltsave                              */
138         .long   0                         /* intsave                              */
139         .long   0                         /* isleaf                               */
140         .long   0                         /* IsSync                               */
141         .long   32                        /* frame size                           */
142         .long   0                         /* method pointer (pointer to name)     */
143
144 asm_calljavafunction:
145 asm_calljavafunction_int:
146         push    %ebp                      /* allocate stack space                 */
147         mov     %esp, %ebp
148
149         push    %ebx                      /* save registers                       */
150         push    %esi
151         push    %edi
152         
153         sub     $32,%esp                  /* pass the remaining parameters        */
154         xor     %edx,%edx
155
156         mov     %edx,28(%esp)             /* convert parms to 8 byte              */
157         mov     24(%ebp),%eax
158         mov     %eax,24(%esp)
159                 
160         mov     %edx,20(%esp)
161         mov     20(%ebp),%eax
162         mov     %eax,16(%esp)
163
164         mov     %edx,12(%esp)
165         mov     16(%ebp),%eax
166         mov     %eax,8(%esp)
167
168         mov     %edx,4(%esp)
169         mov     12(%ebp),%eax
170         mov     %eax,(%esp)
171
172         mov     8(%ebp),%eax              /* move function pointer to %eax        */
173
174         lea     asm_call_jit_compiler,%edx 
175         call    *%edx                     /* call JIT compiler                    */
176         
177         add     $32,%esp
178         pop     %edi                      /* restore registers                    */
179         pop     %esi
180         pop     %ebx
181         leave
182         ret
183
184 calljava_xhandler:
185         push    %eax                      /* pass exception pointer               */
186         call    builtin_throw_exception
187         add     $4,%esp
188
189         add     $32,%esp
190         pop     %edi                      /* restore registers                    */
191         pop     %esi
192         pop     %ebx
193         leave
194         xor     %eax,%eax                 /* return NULL                          */
195         ret
196
197
198 /********************* function asm_calljavafunction ***************************
199 *                                                                              *
200 *   This function calls a Java-method (which possibly needs compilation)       *
201 *   with up to 4 address parameters.                                           *
202 *                                                                              *
203 *   This functions calls the JIT-compiler which eventually translates the      *
204 *   method into machine code.                                                  *
205 *                                                                              *
206 *   C-prototype:                                                               *
207 *    javaobject_header *asm_calljavafunction2(methodinfo *m,                   *
208 *         u4 count, u4 size, void *callblock);                                 *
209 *                                                                              *
210 *******************************************************************************/
211
212 call_name2:
213         .align  8
214
215         .long   0                         /* catch type all                       */
216         .long   calljava_xhandler2        /* handler pc                           */
217         .long   calljava_xhandler2        /* end pc                               */
218         .long   asm_calljavafunction2     /* start pc                             */
219         .long   1                         /* extable size                         */
220         .long   0                         /* line number table start              */
221         .long   0                         /* line number table size               */
222         .long   0                         /* fltsave                              */
223         .long   0                         /* intsave                              */
224         .long   0                         /* isleaf                               */
225         .long   0                         /* IsSync                               */
226         .long   32                        /* frame size                           */
227         .long   0                         /* method pointer (pointer to name)     */
228
229 asm_calljavafunction2:
230 asm_calljavafunction2int:
231 asm_calljavafunction2long:
232 asm_calljavafunction2float:
233 asm_calljavafunction2double:
234         push    %ebp
235         mov     %esp,%ebp                 /* save stackptr                        */
236
237         push    %ebx                      /* save registers                       */
238         push    %esi
239         push    %edi
240
241         mov     20(%ebp),%eax             /* pointer to arg block                 */
242         mov     12(%ebp),%ecx             /* arg count                            */
243         test    %ecx,%ecx                 /* maybe we have no args                */
244         jle     calljava_copydone
245
246         mov     %ecx,%edx                 /* calculate stack size                 */
247         shl     $3,%edx
248         mov     %edx,%esi                 /* save in callee saved register        */
249         sub     %esi,%esp                 /* stack frame for arguments            */
250         mov     %esp,%edi
251
252 calljava_copyloop:
253         mov     offjniitem(%eax),%edx
254         mov     %edx,0(%edi)
255         mov     offjniitem+4(%eax),%edx
256         mov     %edx,4(%edi)
257
258         sub     $1,%ecx                   /* are there any args left?             */
259         test    %ecx,%ecx
260         jle     calljava_copydone
261
262         add     $sizejniblock,%eax        /* goto next argument block             */
263         add     $8,%edi                   /* increase sp to next argument         */
264         jmp     calljava_copyloop
265
266 calljava_copydone:
267         mov     8(%ebp),%eax              /* move function pointer to %eax        */
268
269         lea     asm_call_jit_compiler,%edx 
270         call    *%edx                     /* call JIT compiler                    */
271         
272 calljava_return2:
273         add     %esi,%esp                 /* remove arg stack frame               */
274         pop     %edi                      /* restore registers                    */
275         pop     %esi
276         pop     %ebx
277         leave
278         ret
279
280 calljava_xhandler2:
281         push    %eax                      /* pass exception pointer               */
282         call    builtin_throw_exception
283         add     $4,%esp
284     
285         add     %esi,%esp                 /* remove arg stack frame               */
286         pop     %edi                      /* restore registers                    */
287         pop     %esi
288         pop     %ebx
289         leave
290         xor     %eax,%eax                 /* return NULL                          */
291         ret
292
293
294 /****************** function asm_call_jit_compiler *****************************
295 *                                                                              *
296 *   invokes the compiler for untranslated JavaVM methods.                      *
297 *                                                                              *
298 *   Register R0 contains a pointer to the method info structure (prepared      *
299 *   by createcompilerstub). Using the return address in R26 and the            *
300 *   offset in the LDA instruction or using the value in methodptr R28 the      *
301 *   patching address for storing the method address can be computed:           *
302 *                                                                              *
303 *   method address was either loaded using                                     *
304 *                                                                              *
305 *   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special       *
306 *   i386_call_reg(REG_ITMP2)                                                   *
307 *                                                                              *
308 *   or                                                                         *
309 *                                                                              *
310 *   i386_mov_membase_reg(REG_SP, 0, REG_ITMP1)    ; invokevirtual/interface    *
311 *   i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2)                *
312 *   i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \                *
313 *       sizeof(methodptr) * m->vftblindex, REG_ITMP1)                          *
314 *   i386_call_reg(REG_ITMP1)                                                   *
315 *                                                                              *
316 *   in the static case the method pointer can be computed using the            *
317 *   return address and the lda function following the jmp instruction          *
318 *                                                                              *
319 *******************************************************************************/
320
321 asm_call_jit_compiler:
322         push    %ebx                /* save register                              */
323     push    %ebp
324                         
325         mov     8(%esp),%ebp        /* get return address (2 push)                */
326         mov     -1(%ebp),%bl        /* get function code                          */
327         cmp     $0xd1,%bl           /* called with `call *REG_ITMP2' (%ecx)?      */
328         jne             L_not_static_special
329
330         sub     $6,%ebp             /* calculate address of immediate             */
331         jmp             L_call_jit_compile
332                 
333 L_not_static_special:
334         cmp     $0xd0,%bl           /* called with `call *REG_ITMP1' (%eax)       */
335         jne             L_not_virtual_interface
336         
337         sub     $6,%ebp             /* calculate address of offset                */
338         mov     (%ebp),%ebp         /* get offset                                 */
339         add     itmp2,%ebp          /* add base address to get method address     */
340         jmp             L_call_jit_compile
341
342 L_not_virtual_interface:        /* a call from asm_calljavafunction           */
343         xor     %ebp,%ebp
344                 
345 L_call_jit_compile:
346         push    %ebp                /* save address for method pointer            */
347
348         push    %eax                /* push methodpointer on stack                */
349         call    jit_compile
350         add     $4,%esp
351
352         pop     %ebp                /* restore address for method pointer         */
353
354         test    %eax,%eax           /* check for exception                        */
355         je      L_asm_call_jit_compiler_exception
356
357         test    %ebp,%ebp           /* is address == 0 (asm_calljavafunction)     */
358         je              L_call_method
359         
360         mov     %eax,(%ebp)         /* and now save the new pointer               */
361
362 L_call_method:
363         pop     %ebp                /* restore registers                          */
364         pop     %ebx
365                 
366         jmp             *%eax               /* ...and now call the new method             */
367
368 L_asm_call_jit_compiler_exception:
369         pop     %ebp                /* restore registers                          */
370         pop     %ebx
371
372 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
373         call    builtin_asm_get_exceptionptrptr
374         mov     %eax,%ecx
375 #else
376         lea     _exceptionptr,%ecx
377 #endif
378         mov     (%ecx),%eax         /* get the exception pointer                  */
379         movl    $0,(%ecx)           /* clear the exception pointer                */
380
381         pop     %ecx                /* delete return address                      */
382         sub     $2,%ecx             /* faulting address is return adress - 2      */
383
384 L_refillinStacktrace:               /*a compilation error should cause a stacktrace
385                                     which starts at the method call, which caused
386                                     the compilation of the new function. Until this
387                                     point the trace is invalid anyways, since it is
388                                     not complete. Compared to other runtimes it will
389                                     not be correct either, since we report eg class
390                                     not found errors too early, since we always
391                                     compile methods completely. The native info
392                                     should be moved around the jit call to get
393                                     a more compliant trace for the "exception in
394                                     initializer" case*/
395         push %ecx               /* store fault adress */
396         push %eax               /* temporarily save exception pointer*/
397         push $0                 /* internal function */
398         call builtin_asm_get_stackframeinfo
399         push %eax       /* save location of thread specific stack info head pointer */
400         mov (%eax),%ecx /* save old value of pointer*/
401         push %ecx
402         mov %esp,(%eax) /*store pointer to this structure*/
403         mov 12(%esp),%eax  /* get the exception pointer again*/
404         movl $0,12(%esp) /*java stack begins just above structure*/
405         push $0 /*used for the jni_callblock structure*/
406         push %eax /*save eax for later */
407         /* get fillInStackTrace method*/
408         push utf_void__java_lang_Throwable
409         push utf_fillInStackTrace
410         mov offobjvftbl(%eax),%ecx
411         mov offclass(%ecx),%eax
412         push %eax
413         call class_resolvemethod
414         add $12,%esp
415         push $0
416         push $4 /*TYPE_ADR*/
417         push %esp
418         push $sizejniblock
419         push $1
420         push %eax
421         call asm_calljavafunction2
422         add $24,%esp
423
424         /*remove native stack info */
425         mov 8(%esp),%ecx
426         mov 12(%esp),%eax
427         mov %ecx,(%eax)
428         mov (%esp),%eax
429         add $24,%esp
430         pop %ecx
431
432         
433         jmp     asm_handle_exception
434
435
436 /********************* function asm_handle_exception ***************************
437 *                                                                              *
438 *   This function handles an exception. It does not use the usual calling      *
439 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
440 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
441 *   the local exception table for a handler. If no one is found, it unwinds    *
442 *   stacks and continues searching the callers.                                *
443 *                                                                              *
444 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
445 *                                                                              *
446 *******************************************************************************/
447
448 asm_handle_nat_exception:
449                 add     $4,%esp                                         /* clear return address of native stub */
450                 
451 asm_handle_exception:
452 asm_handle_exception_loop:
453                 push    %ebp
454                 mov     %esp,%ebp
455         
456                 push    %eax                                            /* save exception pointer         */
457                 push    %ecx                        /* save exception pc              */
458
459                 call    codegen_findmethod          /* get the data segment ptr       */
460                 mov     %eax,%edx
461                         
462                 mov     -4(%ebp),%eax
463                 mov     -8(%ebp),%ecx               /* could be changed in findmethod */
464
465                 push    %edx                                            /* save data segment pointer      */
466                 push    %ebx
467                 push    %esi
468                 push    %edi
469                 
470 ex_stack_loop:
471                 sub     $20,%esp
472                 mov     %eax,(%esp)                                     /* exception pointer              */
473                 mov     MethodPointer(%edx),%eax        /* method pointer                 */
474                 mov     %eax,4(%esp)
475                 mov     %ecx,8(%esp)                            /* exception pc                   */
476                 movl    $0,12(%esp)                 /* line number                    */
477                 movl    $1,16(%esp)                                     /* set no unwind flag             */
478                 call    builtin_trace_exception
479                 add     $20,%esp
480                 mov     -12(%ebp),%esi                          /* %esi = data segment pointer    */
481                 mov     ExTableSize(%esi),%ecx          /* %ecx = exception table size    */
482                 test    %ecx,%ecx                                       /* if empty table skip            */
483                 je      empty_table
484
485                 lea             ExTableStart(%esi),%edi         /* %edi = start of exception table*/
486                 mov     -4(%ebp),%eax               /* get xptr                       */
487                 
488 ex_table_loop:
489                 mov     -8(%ebp),%edx                           /* get xpc                        */
490
491                 mov     ExStartPC(%edi),%ebx            /* %ebx = exception start pc      */
492                 cmp     %edx,%ebx                                       /* %ebx = (startpc <= xpc)        */
493                 jg      ex_table_cont                           /* if (false) continue            */
494                 mov     ExEndPC(%edi),%ebx                      /* %ebx = exception end pc        */
495                 cmp     %ebx,%edx                                       /* %ebx = (xpc < endpc)           */
496                 jge     ex_table_cont                           /* if (false) continue            */
497                 mov     ExCatchType(%edi),%ebx          /* arg1 = exception catch type    */
498                 test    %ebx,%ebx                                       /* NULL catches everything        */
499                 je      ex_handle_it
500
501         cmpl    $0,offclassloaded(%ebx)     /* check if class is loaded           */
502         jne     L_class_loaded
503
504         sub     $3*4,%esp
505         mov     %eax,1*4(%esp)              /* save not callee saved regs         */
506         mov     %ecx,2*4(%esp)
507
508         mov     %ebx,0*4(%esp)              /* exception class is argument        */
509         call    load_class_bootstrap
510
511         mov     0*4(%esp),%ebx
512         mov     1*4(%esp),%eax
513         mov     2*4(%esp),%ecx
514         add     $3*4,%esp
515
516 L_class_loaded:
517         cmpl    $0,offclasslinked(%ebx)
518         jne     L_class_linked
519
520         sub     $3*4,%esp
521         mov     %eax,1*4(%esp)              /* save not callee saved regs         */
522         mov     %ecx,2*4(%esp)
523
524         mov     %ebx,0*4(%esp)              /* exception class is argument        */
525         call    link_class
526
527         mov     0*4(%esp),%ebx
528         mov     1*4(%esp),%eax
529         mov     2*4(%esp),%ecx
530         add     $3*4,%esp
531
532 L_class_linked:
533 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
534         push    %ebx
535
536 _crit_restart1:
537         mov     0(%esp),%ebx
538 #endif
539                 
540 _crit_begin1:
541         mov     offobjvftbl(%eax),%esi          /* %esi = vftblptr(xptr)              */
542         mov     offclassvftbl(%ebx),%ebx    /* %ebx = vftblptr(catchtype) class (not obj) */
543         mov     offbaseval(%esi),%esi           /* %esi = baseval(xptr)               */
544         mov     offbaseval(%ebx),%edx           /* %edx = baseval(catchtype)          */
545         mov     offdiffval(%ebx),%ebx           /* %ebx = diffval(catchtype)          */
546 _crit_end1:
547         sub     %edx,%esi                                       /* %esi = baseval(xptr) - baseval(catchtype) */
548
549 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
550         add     $4,%esp
551 #endif
552         
553         cmp     %ebx,%esi                                       /* xptr is instanceof catchtype       */
554         ja      ex_table_cont
555                 
556 ex_handle_it:
557                 mov     ExHandlerPC(%edi),%edx
558                 
559                 pop     %edi                        /* restore registers              */
560                 pop     %esi
561                 pop     %ebx
562         add     $8,%esp                     /* suck %ecx, %edx                */
563         pop     %eax                        /* restore xptr                   */
564
565                 leave
566                 jmp             *%edx                       /* jump to exception handler      */
567
568 ex_table_cont:
569                 lea     ExEntrySize(%edi),%edi
570                 dec     %ecx
571                 test    %ecx,%ecx
572                 jg      ex_table_loop
573                 
574 empty_table:
575         pop     %edi
576         pop     %esi
577         pop     %ebx
578         pop     %edx                        /* restore data segment pointer   */
579         pop     %ecx
580         pop     %eax
581         pop     %ebp
582
583         push    %eax                        /* save exception pointer         */
584         
585 ex_already_cleared:
586                 mov     IsSync(%edx),%eax                       /* %eax = SyncOffset              */
587                 test    %eax,%eax                                       /* if zero no monitorexit         */
588                 je      no_monitor_exit
589
590 #if defined(USE_THREADS)
591         add     %esp,%eax
592         mov     -4(%eax),%eax               /* we have the xptr on the stack  */
593         push    %edx                        /* save regs                      */
594         push    %eax
595                 call    builtin_monitorexit
596                 add     $4,%esp
597         pop     %edx                        /* restore regs                   */
598 #endif
599
600 no_monitor_exit:
601         mov     %esp,%eax
602         add     FrameSize(%edx),%eax        /* %eax = frame size              */
603         add     $4,%eax                     /* we have the xptr on the stack  */
604         
605                 mov     IntSave(%edx),%ecx          /* %ecx = saved int register count*/
606                 test    %ecx,%ecx
607                 je      noint
608                 cmp     $1,%ecx
609                 je      int1
610                 cmp     $2,%ecx
611                 je      int2
612                 cmp     $3,%ecx
613                 je      int3
614
615 int4:   
616                 mov     -32(%eax),%ebx
617
618 int3:   
619                 mov     -24(%eax),%ebp
620
621 int2:   
622                 mov     -16(%eax),%esi
623
624 int1:   
625                 mov     -8(%eax),%edi
626
627                 shl     $3,%ecx                                         /* multiply by 8 bytes             */
628                 sub     %ecx,%eax
629                 
630 noint:
631                 mov     FltSave(%edx),%ecx                      /* %ecx = saved flt register count */
632                 test    %ecx,%ecx
633                 je      noflt
634                 cmp     $1,%ecx
635                 je      flt1
636                 cmp     $2,%ecx
637                 je      flt2
638                 cmp     $3,%ecx
639                 je      flt3
640                 
641 flt4:   
642                 fldl    -32(%eax)
643                 fstp    %st(1)
644
645 flt3:   
646                 fldl    -24(%eax)
647                 fstp    %st(2)
648                 
649 flt2:   
650                 fldl    -16(%eax)
651                 fstp    %st(3)
652                 
653 flt1:   
654                 fldl    -8(%eax)
655                 fstp    %st(4)
656                 
657 noflt:
658         pop     %eax                        /* restore exception pointer      */
659         
660         mov     FrameSize(%edx),%ecx        /* %ecx = frame size              */
661         add     %ecx,%esp                   /* unwind stack                   */
662         
663                 pop     %ecx                        /* the new xpc is return address  */
664                 sub     $2,%ecx
665                 
666                 jmp             asm_handle_exception_loop
667                 
668
669 /* asm_check_clinit ************************************************************
670
671    DOCUMENT ME!!!
672
673    Stack layout:
674
675         16  ra      ; return address of patched call in java machine code
676         12  xmcode  ; additional machine code (only for i386 and x86_64)
677         8   mcode   ; machine code to patch back in
678         4   class   ; pointer to class
679         0   sp      ; stack pointer of java stack frame + return address
680
681 *******************************************************************************/
682
683 asm_check_clinit:
684         mov     4(%esp),%eax                /* get fieldinfo's class pointer      */
685         mov     offclassinit(%eax),%eax     /* get initialized flag               */
686         test    %eax,%eax
687         jnz     L_is_initialized
688
689         /*3*4 bytes*/
690         mov 16(%esp),itmp1
691         push itmp1                        /*return adress into java machine code */
692         mov 4(%esp),itmp1
693         push itmp1                        /*begin of java stack frame*/
694         pushl $0                           /*internal (invisible) method*/
695         call asm_prepare_native_stackinfo /*puts additional 2 *4 bytes of
696                                                 data onto the stack */
697
698         sub     $4,%esp
699         mov     20+4+4(%esp),itmp1          /* get class pointer                  */
700         mov     itmp1,(%esp)                /* store class pointer as a0          */
701         call    initialize_class            /* call initialize class function     */
702         add     $4,%esp
703
704         call asm_remove_native_stackinfo  /* removes 4* 4 bytes and leaves ret
705                                                  into java machine code on stack  */
706         add     $4,%esp                   /* ret address no longer needed, is still
707                                                 on stack a few bytes above */
708
709         test    %eax,%eax                   /* we had an exception                */
710         je      L_initializererror
711
712 L_is_initialized:
713         mov     16(%esp),itmp1              /* get return address                 */
714         sub     $5,itmp1                    /* remove size of `call rel32'        */
715
716         mov     12(%esp),itmp2              /* get xmcode machine code            */
717         movb    itmp2b,(itmp1)              /* patch back in 1 byte               */
718         mov     8(%esp),itmp2               /* get mcode machine code             */
719         mov     itmp2,1(itmp1)              /* patch back in 4 bytes              */
720
721         add     $(5*4),%esp                 /* remove stub stack frame incl. ra   */
722
723         jmp     *itmp1                      /* jump to patched code an execute it */
724
725 L_initializererror:
726         add     $(4*4),%esp                 /* remove stub stack frame            */
727
728 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
729         call    builtin_asm_get_exceptionptrptr
730         mov     %eax,%ecx
731         mov     (%ecx),%eax                 /* get the exception pointer          */
732         movl    $0,(%ecx)                   /* clear the exception pointer        */
733 #else
734         lea     _exceptionptr,%ecx
735         mov     (%ecx),%eax                 /* get the exception pointer          */
736         movl    $0,(%ecx)                   /* clear the exception pointer        */
737 #endif
738
739         pop     itmp2                       /* get and delete ra                  */
740         sub     $5,itmp2                    /* faulting address is ra - 5         */
741
742         jmp     asm_handle_exception
743
744
745 /* asm_patcher_builtin_new *****************************************************
746
747    XXX
748
749    Arguments:
750      a0   contains the class reference
751
752 *******************************************************************************/
753
754 asm_patcher_builtin_new:
755         mov     4*1(%esp),itmp1             /* get the class reference            */
756         push    itmp1
757         call    helper_resolve_classinfo    /* call the helper function           */
758         add     $(4*1),%esp                 /* remove stack frame                 */
759
760         test    v0,v0                       /* exception thrown?                  */
761         jz      L_asm_patcher_exception
762
763         pop     itmp2                       /* get return address                 */
764         sub     $(2+5+7),itmp2              /* 2 (call) + 5 (movi) + 7 (movi)     */
765         mov     v0,3(itmp2)                 /* patch in new classinfo*: 3 (mov)   */
766
767         lea     builtin_new,itmp1           /* get address from builtin_new       */
768         mov     itmp1,8(itmp2)              /* patch back function address        */
769         jmp     *itmp2                      /* call new patched code              */
770
771 L_asm_patcher_exception:
772 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
773         call    builtin_asm_get_exceptionptrptr
774         mov     v0,itmp2
775 #else
776         lea     _exceptionptr,itmp2
777 #endif
778         mov     (itmp2),xptr                /* get the exception pointer          */
779         movl    $0,(itmp2)                  /* clear the exception pointer        */
780
781         pop     itmp2                       /* get and remove return address      */
782         sub     $5,itmp2                    /* faulting address is ra - 5         */
783         jmp     asm_handle_exception
784
785
786 /* asm_patcher_invokespecial ***************************************************
787
788    XXX
789
790    Stack layout:
791
792         16  ra      ; return address of patched call in java machine code
793         12  xmcode  ; additional machine code (only for i386 and x86_64)
794         8   mcode   ; machine code to patch back in
795         4   class   ; pointer to class
796         0   sp      ; stack pointer of java stack frame + return address
797
798 *******************************************************************************/
799
800 asm_patcher_invokestatic_special:
801         mov     4*1(%esp),itmp1             /* pass unresolved_method pointer     */
802         push    itmp1
803         call    helper_resolve_methodinfo_stubroutine /* call the helper function */
804         add     $(4*1),%esp                 /* remove stack frame                 */
805
806         test    v0,v0                       /* exception thrown?                  */
807         jz      L_asm_patcher_exception
808
809         mov     16(%esp),itmp2              /* get return address                 */
810         sub     $5,itmp2                    /* remove size of `call rel32'        */
811
812         mov     12(%esp),itmp3              /* get xmcode machine code            */
813         movb    itmp3b,(itmp2)              /* patch back in 1 byte               */
814         mov     8(%esp),itmp3               /* get mcode machine code             */
815         mov     itmp3,1(itmp2)              /* patch back in 4 bytes              */
816
817         add     $(5*4),%esp                 /* remove stub stack frame incl. ra   */
818
819         mov     v0,3+2+1(itmp2)             /* patch stubroutine: 3 + 2 + 1 (mov) */
820         jmp     *itmp2                      /* call new patched code              */
821
822
823 /********************* function asm_builtin_monitorenter ***********************
824 *                                                                              *
825 *   Does null check and calls monitorenter or throws an exception              *
826 *                                                                              *
827 *******************************************************************************/
828
829 #if defined(USE_THREADS)
830 asm_builtin_monitorenter:
831         cmpl    $0,4(%esp)
832         je      nb_monitorenter             /* if (null) throw exception          */
833         jmp             builtin_monitorenter        /* else call builtin_monitorenter     */
834
835 nb_monitorenter:
836         mov string_java_lang_NullPointerException,%eax
837         pop %ecx
838         sub $2,%ecx
839         jmp asm_throw_and_handle_exception
840
841 #if 0
842         push    string_java_lang_NullPointerException
843         call    new_exception
844         add     $(1*4),%esp
845         
846         pop     %ecx                        /* delete return address              */
847         sub     $2,%ecx                     /* faulting address is return adress - 2 */
848         jmp     asm_handle_exception
849 #endif          
850 #endif
851
852
853 /********************* function asm_builtin_monitorexit ************************
854 *                                                                              *
855 *   Does null check and calls monitorexit or throws an exception               *
856 *                                                                              *
857 *******************************************************************************/
858
859 #if defined(USE_THREADS)
860 asm_builtin_monitorexit:
861         mov     4(%esp),%eax
862     test    %eax,%eax
863         je      nb_monitorexit              /* if (null) throw exception          */
864     push    %ecx                        /* save registers which could be used */
865     push    %edx
866     push    %eax
867         call    builtin_monitorexit         /* else call builtin_monitorenter     */
868     add     $4,%esp
869     pop     %edx                        /* restore registers which could be used */
870     pop     %ecx
871     ret
872
873 nb_monitorexit:
874         mov string_java_lang_NullPointerException,%eax
875         pop %ecx
876         sub $2,%ecx
877         jmp asm_throw_and_handle_exception
878
879 #if 0
880         push    string_java_lang_NullPointerException
881         call    new_exception
882         add     $(1*4),%esp
883         
884         pop     %ecx                    /* delete return address              */
885         sub     $2,%ecx                 /* faulting address is return adress - 2 */
886         jmp     asm_handle_exception
887 #endif
888 #endif
889
890
891 /************************ function asm_builtin_ldiv ****************************
892 *                                                                              *
893 *   Does null check and calls ldiv or throws an exception                      *
894 *                                                                              *
895 *******************************************************************************/
896
897 asm_builtin_ldiv:
898         mov     12(%esp),%eax
899         or      16(%esp),%eax
900         test    %eax,%eax                   /* if (null) throw exception          */
901         je      nb_ldiv
902
903         jmp     builtin_ldiv
904
905 nb_ldiv:
906         pop %ecx
907         sub $2,%ecx
908         jmp asm_throw_and_handle_hardware_arithmetic_exception
909 #if 0
910         push    string_java_lang_ArithmeticException_message
911         push    string_java_lang_ArithmeticException
912         call    new_exception_message
913         add     $(2*4),%esp
914         
915         pop     %ecx                        /* delete return address              */
916         sub     $2,%ecx                     /* faulting address is return adress - 2 */
917         jmp     asm_handle_exception
918 #endif                          
919
920 /************************ function asm_builtin_lrem ****************************
921 *                                                                              *
922 *   Does null check and calls lrem or throws an exception                      *
923 *                                                                              *
924 *******************************************************************************/
925
926 asm_builtin_lrem:
927         mov     12(%esp),%eax
928         or      16(%esp),%eax
929         test    %eax,%eax                   /* if (null) throw exception          */
930         je      nb_lrem
931
932         jmp     builtin_lrem
933
934 nb_lrem:
935         pop %ecx
936         sub $2,%ecx
937         jmp asm_throw_and_handle_hardware_arithmetic_exception
938 #if 0
939         push    string_java_lang_ArithmeticException_message
940         push    string_java_lang_ArithmeticException
941         call    new_exception_message
942         add     $(2*4),%esp
943
944         pop     %ecx                        /* delete return address              */
945         sub     $2,%ecx                     /* faulting address is return adress - 2 */
946         jmp     asm_handle_exception
947 #endif          
948
949 /************************ function asm_builtin_x2x *****************************
950 *                                                                              *
951 *   Wrapper functions for corner cases                                         *
952 *                                                                              *
953 *******************************************************************************/
954
955 asm_builtin_f2i:
956         sub     $4,%esp
957         fsts    (%esp)
958         call    builtin_f2i
959         add     $4,%esp
960         ret
961
962 asm_builtin_d2i:
963         sub     $8,%esp
964         fstl    (%esp)
965         call    builtin_d2i
966         add     $8,%esp
967         ret
968
969 asm_builtin_f2l:
970         sub     $4,%esp
971         fsts    (%esp)
972         call    builtin_f2l
973         add     $4,%esp
974         ret
975
976 asm_builtin_d2l:
977         sub     $8,%esp
978         fstl    (%esp)
979         call    builtin_d2l
980         add     $8,%esp
981         ret
982
983
984 /******************* function asm_builtin_checkarraycast ***********************
985 *                                                                              *
986 *   Does the cast check and eventually throws an exception                     *
987 *                                                                              *
988 *******************************************************************************/
989
990 asm_builtin_checkarraycast:
991         sub             $8,%esp                     /* build stack frame (2 * 4 bytes)    */
992
993         mov             12(%esp),%eax               /* 8 (frame) + 4 (return)             */
994         mov             %eax,(%esp)                 /* save object pointer                */
995
996         mov             20(%esp),%eax
997         mov             %eax,4(%esp)
998
999         call    builtin_checkarraycast      /* builtin_checkarraycast             */
1000
1001         test    %eax,%eax                   /* if (false) throw exception         */
1002         je              nb_carray_throw
1003
1004         mov             12(%esp),%eax               /* return object pointer              */
1005         add             $8,%esp
1006         ret
1007
1008 nb_carray_throw:
1009         add $8,%esp
1010         mov string_java_lang_ClassCastException,%eax
1011         pop %ecx
1012         sub $2,%ecx
1013         jmp asm_throw_and_handle_exception
1014 #if 0
1015         push    string_java_lang_ClassCastException
1016         call    new_exception
1017         add     $(1*4),%esp
1018         
1019         add             $8,%esp
1020         
1021         pop             %ecx                        /* delete return address              */
1022         sub             $2,%ecx                     /* faulting address is return adress - 2 */
1023         jmp             asm_handle_exception
1024 #endif
1025                 
1026 /* asm_builtin_newarray ********************************************************
1027 *                                                                              *
1028 *   Does the cast check and eventually throws an exception                     *
1029 *                                                                              *
1030 *******************************************************************************/
1031
1032 asm_builtin_newarray:
1033         sub     $8,%esp                     /* build stack frame (2 * 4 bytes)    */
1034
1035         mov     12(%esp),%eax
1036         mov     %eax,(%esp)
1037
1038         mov     20(%esp),%eax
1039         mov     %eax,4(%esp)
1040
1041         call    builtin_newarray
1042
1043         add     $8,%esp
1044         ret
1045
1046                 
1047 /******************* function asm_builtin_aastore ******************************
1048 *                                                                              *
1049 *   Does the cast check and eventually throws an exception                     *
1050 *                                                                              *
1051 *******************************************************************************/
1052
1053 asm_builtin_aastore:
1054         sub     $12,%esp                    /* build stack frame (3 * 4 bytes)    */
1055
1056         mov     16(%esp),%eax               /* 12 (frame) + 4 (return)            */
1057         test    %eax,%eax                   /* if null pointer throw exception    */
1058         je      nb_aastore_null
1059
1060         mov     offarraysize(%eax),%edx /* load size                          */
1061         mov     24(%esp),%ecx               /* index                              */
1062         cmp     %edx,%ecx                   /* do bound check                     */
1063         jae     nb_aastore_bound            /* if out of bounds throw exception   */
1064
1065         shl     $2,%ecx                     /* index * 4                          */
1066         add     %eax,%ecx                   /* add index * 4 to arrayref          */
1067            
1068         mov     %ecx,8(%esp)                /* save store position                */
1069            
1070         mov     16(%esp),%eax               /* 12 (frame) + 4 (return)            */
1071         mov     %eax,(%esp)
1072            
1073         mov     32(%esp),%eax               /* object is second argument          */
1074         mov     %eax,4(%esp)
1075         
1076         call    builtin_canstore            /* builtin_canstore(arrayref,object)  */
1077
1078         test    %eax,%eax                   /* if (false) throw exception         */
1079         je      nb_aastore_store
1080
1081         mov     32(%esp),%eax
1082         mov     8(%esp),%ecx
1083         mov     %eax,offobjarrdata(%ecx)    /* store objectptr in array           */
1084         
1085         add     $12,%esp
1086         ret
1087
1088 nb_aastore_null:
1089         add $12,%esp
1090         mov string_java_lang_NullPointerException,%eax
1091         pop %ecx
1092         sub $2,%ecx
1093         jmp asm_throw_and_handle_exception
1094
1095 #if 0
1096         push    string_java_lang_NullPointerException
1097         call    new_exception
1098         add     $(1*4),%esp
1099         
1100         add     $12,%esp
1101         pop     %ecx                        /* delete return address              */
1102         sub     $2,%ecx                     /* faulting address is return adress - 2 */
1103         jmp             asm_handle_exception
1104 #endif
1105 nb_aastore_bound:
1106         add     $12,%esp
1107         mov     %ecx,%eax                        /* itmp2 contains array index         */
1108         pushl   $0  /*directly below return adress*/
1109         pushl   $0  /*internal (invisible) method*/
1110         call    asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
1111
1112         push    %eax
1113         call    new_arrayindexoutofboundsexception
1114         add     $(1*4),%esp
1115
1116         call    asm_remove_native_stackinfo /*return adress is the first on stack again*/
1117
1118         pop     %ecx                        /* delete return address              */
1119         sub     $2,%ecx                     /* faulting address is return adress - 2 */
1120         jmp     asm_handle_exception
1121                 
1122 nb_aastore_store:
1123         add     $12,%esp
1124
1125         mov string_java_lang_ArrayStoreException,%eax
1126         pop %ecx
1127         sub $2,%ecx
1128         jmp asm_throw_and_handle_exception
1129
1130 #if 0
1131         push    string_java_lang_ArrayStoreException
1132         call    new_exception
1133         add     $(1*4),%esp
1134         
1135         add     $12,%esp
1136         pop     %ecx                        /* delete return address              */
1137         sub     $2,%ecx                     /* faulting address is return adress - 2 */
1138         jmp     asm_handle_exception
1139 #endif
1140                 
1141 /******************* function asm_builtin_arrayinstanceof **********************
1142 *                                                                              *
1143 *   Does the instanceof check of arrays                                        *
1144 *                                                                              *
1145 *******************************************************************************/
1146
1147 asm_builtin_arrayinstanceof:
1148         sub             $8,%esp                     /* build stack frame (2 * 4 bytes)    */
1149
1150         mov     12(%esp),%eax
1151         mov     %eax,(%esp)
1152
1153         mov     20(%esp),%eax
1154         mov     %eax,4(%esp)
1155
1156         call    builtin_arrayinstanceof
1157
1158         add     $8,%esp
1159         ret
1160
1161                 
1162 /******************* function asm_initialize_thread_stack **********************
1163 *                                                                              *
1164 * initialized a thread stack                                                   *
1165 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1166 *                                                                              *
1167 *******************************************************************************/
1168
1169 asm_initialize_thread_stack:
1170                 mov             8(%esp),%eax            /* (to)->stackEnd                     */
1171                 sub             $36,%eax                /* 4 bytes * 8 regs + 4 bytes func    */
1172                                 
1173                 xor             %edx,%edx
1174                 mov             %edx,0(%eax)
1175                 mov             %edx,4(%eax)
1176                 mov             %edx,8(%eax)
1177                 mov             %edx,12(%eax)
1178                 mov             %edx,16(%eax)
1179                 mov             %edx,20(%eax)
1180                 mov     %edx,24(%eax)
1181                 mov     %edx,28(%eax)
1182                                 
1183                 mov     4(%esp),%edx            /* save (u1*) (func)                  */
1184                 mov     %edx,32(%eax)
1185
1186                 ret                             /* return restorepoint in %eax        */
1187
1188
1189 /******************* function asm_perform_threadswitch *************************
1190 *                                                                              *
1191 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
1192 *                                                                              *
1193 *   performs a threadswitch                                                    *
1194 *                                                                              *
1195 *******************************************************************************/
1196
1197 asm_perform_threadswitch:
1198         sub     $36,%esp
1199            
1200         mov     %eax,0(%esp)
1201         mov     %ecx,4(%esp)
1202         mov     %edx,8(%esp)
1203         mov     %ebx,12(%esp)
1204         mov     %esp,16(%esp)
1205         mov     %ebp,20(%esp)
1206         mov     %esi,24(%esp)
1207         mov     %edi,28(%esp)
1208            
1209         mov     36(%esp),%eax         /* save current return address              */
1210         mov     %eax,32(%esp)
1211            
1212         mov     40(%esp),%eax         /* first argument **from                    */
1213         mov     %esp,0(%eax)
1214            
1215         mov     48(%esp),%eax         /* third argument **stackTop                */
1216         mov     %esp,0(%eax)
1217            
1218         mov     44(%esp),%eax         /* second argument **to                     */
1219         mov     0(%eax),%esp          /* load new stack pointer                   */
1220            
1221         mov     0(%esp),%eax
1222         mov     4(%esp),%ecx
1223         mov     8(%esp),%edx
1224         mov     12(%esp),%ebx
1225                                       /* skip stack pointer                       */
1226         mov     20(%esp),%ebp
1227         mov     24(%esp),%esi
1228         mov     28(%esp),%edi
1229            
1230         add     $32,%esp              /* leave return address on stack            */
1231         ret
1232                 
1233
1234 /********************* function asm_switchstackandcall *************************
1235 *                                                                              *
1236 *  int asm_switchstackandcall (void *stack, void *func, void **stacktopsave,   *
1237 *                                      void *p);                                       *
1238 *                                                                              *
1239 *   Switches to a new stack, calls a function and switches back.               *
1240 *       a0      new stack pointer                                              *
1241 *       a1      function pointer                                               *
1242 *               a2              pointer to variable where stack top should be stored           *
1243 *       a3      pointer to user data, is passed to the function                *
1244 *                                                                              *
1245 *******************************************************************************/
1246
1247 asm_switchstackandcall:
1248         mov     4(%esp),%edx          /* first argument *stack                    */
1249         sub     $8,%edx               /* allocate new stack                       */
1250
1251         mov     (%esp),%eax           /* save return address on new stack         */
1252         mov     %eax,(%edx)
1253
1254         mov     %esp,4(%edx)          /* save old stack pointer on new stack      */
1255
1256         mov     12(%esp),%eax         /* third argument **stacktopsave            */
1257         mov     %esp,(%eax)           /* save old stack pointer to variable       */
1258
1259         mov     8(%esp),%eax          /* load function pointer                    */
1260         mov     16(%esp),%ecx         /* fourth argument *p                       */
1261         
1262         mov     %edx,%esp             /* switch to new stack                      */
1263
1264         sub     $4,%esp
1265         mov     %ecx,0(%esp)          /* pass pointer                             */
1266         call    *%eax                 /* and call function                        */
1267         add     $4,%esp
1268
1269         mov     (%esp),%edx           /* load return address                      */
1270         mov     4(%esp),%esp          /* switch to old stack                      */
1271         mov     %edx,(%esp)
1272         ret
1273
1274                 
1275 asm_throw_and_handle_exception:
1276         push %ecx
1277         pushl $0 /* the pushed XPC is directly below the java frame*/
1278         pushl $0
1279         call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1280         
1281         push %eax
1282         call new_exception
1283         add $4,%esp   /*remove parameter*/
1284
1285         call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1286
1287         pop %ecx
1288         jmp asm_handle_exception
1289         ret /*should never be reached */
1290
1291 asm_throw_and_handle_hardware_arithmetic_exception:
1292         
1293         push %ecx
1294         pushl $0 /* the pushed XPC is directly below the java frame*/
1295         pushl $0
1296         call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1297         
1298         mov string_java_lang_ArithmeticException_message,%eax
1299         push %eax
1300         mov string_java_lang_ArithmeticException,%eax
1301         push %eax
1302
1303         call new_exception_message
1304         add $8,%esp /*remove parameters */
1305
1306         call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1307
1308         pop %ecx
1309         jmp asm_handle_exception
1310         ret /*should never be reached */
1311
1312 asm_builtin_new2:
1313 /*optimize a littlebit */
1314                 mov %esp,%eax
1315 /*DEBUG*/
1316 /*              push %eax
1317                 call i386_native_stub_debug
1318                 pop %eax */
1319                 
1320                 movl 4(%esp),%eax
1321                 mov     offclassinit(%eax),%ecx     /* get initialized flag           */
1322                 test    %ecx,%ecx
1323                 jnz             L_builtin_new_noinit
1324
1325                 mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
1326
1327                 /* 2 *4 bytes, the return adress is used directy */
1328                 pushl $0  /* the structure is placed directly below the java stackframe*/
1329                 pushl $0  /* builtin (invisible) method */
1330                 call  asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
1331 #if 0
1332                 sub             $16,%esp                                 /* build stack frame (4 * 4 bytes) */
1333
1334                 mov             20(%esp),%eax
1335                 mov             %eax,(%esp)
1336
1337                 call    builtin_asm_get_stackframeinfo
1338                 movl    $0,12(%esp)
1339                 mov     %eax,8(%esp)
1340                 mov     (%eax),%ebx
1341                 mov     %ebx,4(%esp)
1342                 mov     %esp,%ecx
1343                 add     $4,%ecx
1344                 mov     %ecx,(%eax)
1345 #endif
1346                 push    %eax
1347                 call    builtin_new
1348                 add     $4,%esp
1349
1350                 call    asm_remove_native_stackinfo /*first element on stack is return adress again*/
1351 #if 0           
1352                 call    
1353                 mov     4(%esp),%ebx
1354                 mov     8(%esp),%ecx
1355                 mov     %ebx,(%ecx)
1356
1357                 add             $16,%esp
1358 #endif
1359                 jmp L_builtin_new_patch
1360
1361
1362 L_builtin_new_noinit:
1363                 mov 4(%esp),%eax
1364                 push %eax
1365                 call builtin_new
1366                 add $4,%esp
1367                 /*jmp L_builtin_new_patch*/
1368
1369 L_builtin_new_patch:
1370 /*add patching code here */
1371                 lea builtin_new,%edx
1372                 mov (%esp),%ecx
1373                 mov %edx,-6(%ecx)       /*patch calling instruction, t directly call builtin_new the next time*/
1374                 ret
1375
1376
1377
1378
1379
1380
1381 asm_getclassvalues_atomic:
1382 _crit_restart2:
1383         mov     4(%esp),%ecx        /* super */
1384         mov     8(%esp),%edx        /* sub */
1385 _crit_begin2:
1386         mov     offbaseval(%ecx),%eax
1387         mov     offdiffval(%ecx),%ecx
1388         mov     offbaseval(%edx),%edx
1389 _crit_end2:
1390         push    %ebx
1391         mov     16(%esp),%ebx      /* out */
1392         mov     %eax,offcast_super_baseval(%ebx)
1393         mov     %ecx,offcast_super_diffval(%ebx)
1394         mov     %edx,offcast_sub_baseval(%ebx)
1395         pop     %ebx
1396         ret
1397
1398         .data
1399
1400 asm_criticalsections:
1401 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1402         .long   _crit_begin1
1403         .long   _crit_end1
1404         .long   _crit_restart1
1405         .long   _crit_begin2
1406         .long   _crit_end2
1407         .long   _crit_restart2
1408 #endif
1409         .long 0
1410
1411
1412
1413 /************************ function asm_prepare_native_stackinfo ****************************
1414 *                                                                                          *
1415 *    creates a stackfame for the begin of a native function (either builtin or not )       *
1416 *    expected stack at begin of function                                                   *
1417 *                                        ....                                              *
1418 *                   address of the jit call which invokes the native                       *
1419 *                   begin address of stack frame of the java method                        *
1420 *                   method pointer or 0 (for built ins)                                    *
1421 *                   return address                                                         *
1422 *                                                                                          *
1423 *    at end of function:                                                                   *
1424 *                                          ...                                             *
1425 *                   address of the jit call which invokes the native                       *
1426 *                   begin address of stack frame of the java method                        *
1427 *                   method pointer or 0 (for built ins)                                    *
1428 *                   address of thread specific top of native list                          *
1429 *                   old value of thread specific head                                      *
1430 *                   return address                                                         *
1431 *                                                                                          *
1432 *                                        ....                                              *
1433 * This thing is less efficient than the original #define (callerside)                      *
1434 * destroyes REG_ITMP2, keeps REG_ITMP1                                                     *
1435 ********************************************************************************************/
1436
1437
1438 asm_prepare_native_stackinfo:
1439         sub $8,%esp
1440         mov 8(%esp),%ecx
1441         mov %ecx,(%esp)
1442         push %eax
1443         lea     builtin_asm_get_stackframeinfo,%ecx
1444         call    *%ecx
1445         mov %eax, 12(%esp)
1446         mov (%eax),%ecx
1447         mov %ecx,8(%esp)
1448         mov %esp,%ecx
1449         add $8,%ecx
1450         mov %ecx,(%eax)
1451         pop %eax
1452         ret
1453 #if 0
1454 #define PREPARE_NATIVE_STACKINFO \
1455     i386_push_reg(cd, REG_ITMP1);       /*save itmp1, needed by some stubs */ \
1456     i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
1457     i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
1458     i386_call_reg(cd, REG_ITMP1);                /*call    codegen_stubcalled*/ \
1459     i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
1460     i386_call_reg(cd, REG_ITMP1);                /*call    builtin_asm_get_stackframeinfo*/ \
1461     i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer  to native call stack*/ \
1462     i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
1463     i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4);     /* store value on stack */ \
1464     i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
1465     i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
1466     i386_mov_imm_membase(cd, 0,REG_SP, 2*4);    /* builtin */
1467 #endif
1468
1469
1470 /************************ function asm_remove _native_stackinfo *******************************************
1471 *                                                                                                         *
1472 *    creates a stackfame for the begin of a native function (either builtin or not)                       *
1473 *    expected stack at begin of function                                                                  *
1474 *                   address of the jit call which invokes the native                                      *
1475 *                   begin address of stack frame of the java method                                       *
1476 *                   method pointer or 0 (for built ins)                                                   *
1477 *                   address thread specific top of native list                                            *
1478 *                   old value of thread specific head                                                     *
1479 *                   return address                                                                        *
1480 *                                                                                                         *
1481 *    at end of function:                                                                                  *
1482 *                             ....                                                                        *
1483 *                   return adresss of the jit call which invokes the native                               *
1484 *                   return address                                                                        *
1485 *                                                                                                         *
1486 *                   REG_ITMP2_XPC = address of the jit call which invokes the native                      *
1487 *                                                                                                         *
1488 *                                                                                                         *
1489 * This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1  *
1490 ***********************************************************************************************************/
1491
1492 asm_remove_native_stackinfo:
1493         mov 4(%esp),%ecx
1494         mov 8(%esp),%edx
1495         mov %ecx,(%edx)
1496         pop %edx
1497         add $16,%esp
1498         push %edx
1499         ret
1500
1501 #if 0
1502 #define REMOVE_NATIVE_STACKINFO \
1503     i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
1504     i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
1505     i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
1506     i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
1507 #endif
1508
1509
1510
1511
1512 /*
1513  * These are local overrides for various environment variables in Emacs.
1514  * Please do not remove this and leave it at the end of the file, where
1515  * Emacs will automagically detect them.
1516  * ---------------------------------------------------------------------
1517  * Local variables:
1518  * mode: asm
1519  * indent-tabs-mode: t
1520  * c-basic-offset: 4
1521  * tab-width: 4
1522  * End:
1523  */