native functions, getClassContext, currentClassLoader implementation (with stack...
[cacao.git] / src / vm / jit / i386 / asmpart.S
1 /* jit/i386/asmpart.S - Java-C interface functions for i386
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    Institut f. Computersprachen, TU Wien
5    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6    S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
7    J. Wenninger
8
9    This file is part of CACAO.
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License as
13    published by the Free Software Foundation; either version 2, or (at
14    your option) any later version.
15
16    This program is distributed in the hope that it will be useful, but
17    WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24    02111-1307, USA.
25
26    Contact: cacao@complang.tuwien.ac.at
27
28    Authors: Andreas Krall
29             Reinhard Grafl
30             Christian Thalinger
31
32    $Id: asmpart.S 930 2004-03-02 21:18:23Z jowenn $
33
34 */
35
36
37 #include "offsets.h"
38
39 /* data segment offsets */
40
41 #define MethodPointer   -4
42 #define FrameSize       -8
43 #define IsSync          -12
44 #define IsLeaf          -16
45 #define IntSave         -20
46 #define FltSave         -24
47 #define ExTableSize     -28
48 #define ExTableStart    -28
49
50 #define ExEntrySize     -16
51 #define ExStartPC       -4
52 #define ExEndPC         -8
53 #define ExHandlerPC     -12
54 #define ExCatchType     -16
55
56                 
57         .text
58
59
60 /********************* exported functions and variables ***********************/
61
62         .globl has_no_x_instr_set
63         .globl asm_calljavafunction
64         .globl asm_calljavafunction2
65         .globl asm_calljavafunction2long
66         .globl asm_calljavafunction2double
67
68         .globl asm_call_jit_compiler
69         .globl asm_dumpregistersandcall
70         .globl asm_handle_builtin_exception
71         .globl asm_handle_nat_exception
72         .globl asm_handle_exception
73         .globl asm_check_clinit
74         .globl asm_builtin_checkcast    
75         .globl asm_builtin_checkarraycast
76         .globl asm_builtin_newarray
77         .globl asm_builtin_anewarray
78         .globl asm_builtin_newarray_array
79         .globl asm_builtin_aastore
80         .globl asm_builtin_monitorenter
81         .globl asm_builtin_monitorexit
82         .globl asm_builtin_ldiv
83         .globl asm_builtin_lrem
84     .globl asm_builtin_f2i
85     .globl asm_builtin_f2l
86     .globl asm_builtin_d2i
87     .globl asm_builtin_d2l
88         .globl asm_builtin_arrayinstanceof
89         .globl asm_perform_threadswitch
90         .globl asm_initialize_thread_stack
91         .globl asm_switchstackandcall
92         .globl asm_getcallingmethod
93         .globl Java_java_lang_VMSecurityManager_getClassContext
94         .globl Java_java_lang_VMSecurityManager_currentClassLoader    
95 /*************************** imported functions *******************************/
96
97         .globl jit_compile
98         .globl builtin_monitorexit
99         .globl builtin_throw_exception
100         .globl builtin_trace_exception
101         .globl class_java_lang_Object
102         .globl findmethod
103         .globl builtin_asm_createclasscontextarray
104         .globl builtin_asm_getclassloader
105 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
106         .globl cast_lock
107         .globl cast_unlock
108 #endif
109
110
111 /*********************** function has_no_x_instr_set ***************************
112 *                                                                              *
113 *   determines if the byte support instruction set (21164a and higher)         *
114 *   is available.                                                              *
115 *                                                                              *
116 *   Use it on i386 architecture to init the fpu.                               *
117 *                                                                              *
118 *******************************************************************************/
119
120 has_no_x_instr_set:
121                 finit                         /* intitialize the fpu                  */
122
123                 pushl   $0x027f   /* Round to nearest, 53-bit mode, exceptions masked */
124                 fldcw   (%esp)
125                 addl    $4,%esp
126                 
127                 xor             %eax,%eax                               /* result code 0 (not used for i386)  */
128                 ret
129
130
131 /********************* function asm_calljavafunction ***************************
132 *                                                                              *
133 *   This function calls a Java-method (which possibly needs compilation)       *
134 *   with up to 4 address parameters.                                           *
135 *                                                                              *
136 *   This functions calls the JIT-compiler which eventually translates the      *
137 *   method into machine code.                                                  *
138 *                                                                              *
139 *   C-prototype:                                                               *
140 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
141 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
142 *                                                                              *
143 *******************************************************************************/
144
145 call_name:
146         .ascii  "calljavafunction\0\0"
147
148         .align  8
149         .long   0                         /* catch type all                       */
150         .long   calljava_xhandler         /* handler pc                           */
151         .long   calljava_xhandler         /* end pc                               */
152         .long   asm_calljavafunction      /* start pc                             */
153         .long   1                         /* extable size                         */
154         .long   0                         /* fltsave                              */
155         .long   0                         /* intsave                              */
156         .long   0                         /* isleaf                               */
157         .long   0                         /* IsSync                               */
158         .long   32                        /* frame size                           */
159         .long   0                         /* method pointer (pointer to name)     */
160
161 asm_calljavafunction:
162                 push    %ebp                  /* allocate stack space                 */
163                 mov             %esp, %ebp
164
165         push    %ebx                  /* save registers                       */
166         push    %esi
167         push    %edi
168         
169                 sub             $32,%esp              /* pass the remaining parameters        */
170                 xor             %edx,%edx
171
172                 mov             %edx,28(%esp)         /* convert parms to 8 byte              */
173                 mov             24(%ebp),%eax
174                 mov             %eax,24(%esp)
175                 
176                 mov             %edx,20(%esp)
177                 mov             20(%ebp),%eax
178                 mov             %eax,16(%esp)
179
180                 mov             %edx,12(%esp)
181                 mov             16(%ebp),%eax
182                 mov             %eax,8(%esp)
183
184                 mov             %edx,4(%esp)
185                 mov             12(%ebp),%eax
186                 mov             %eax,(%esp)
187
188                 mov             8(%ebp),%eax          /* move function pointer to %eax        */
189
190                 lea             asm_call_jit_compiler,%edx 
191                 call    *%edx                 /* call JIT compiler                    */
192         
193 calljava_return:
194         add     $32,%esp
195         pop     %edi                 /* restore registers                     */
196         pop     %esi
197         pop     %ebx
198                 leave
199                 ret
200
201 calljava_xhandler:
202                 push    %eax                              /* pass exception pointer               */
203                 call    builtin_throw_exception
204                 add     $4,%esp
205
206                 add     $32,%esp
207         pop     %edi                 /* restore registers                     */
208         pop     %esi
209         pop     %ebx
210         leave
211                 ret
212                                                 
213
214
215 /********************* function asm_calljavafunction ***************************
216 *                                                                              *
217 *   This function calls a Java-method (which possibly needs compilation)       *
218 *   with up to 4 address parameters.                                           *
219 *                                                                              *
220 *   This functions calls the JIT-compiler which eventually translates the      *
221 *   method into machine code.                                                  *
222 *                                                                              *
223 *   C-prototype:                                                               *
224 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
225 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
226 *                                                                              *
227 *******************************************************************************/
228
229 call_name2:
230         .ascii  "calljavafunction2\0\0"
231
232         .align  8
233         .long   0                         /* catch type all                       */
234         .long   calljava_xhandler2        /* handler pc                           */
235         .long   calljava_xhandler2        /* end pc                               */
236         .long   asm_calljavafunction2     /* start pc                             */
237         .long   1                         /* extable size                         */
238         .long   0                         /* fltsave                              */
239         .long   0                         /* intsave                              */
240         .long   0                         /* isleaf                               */
241         .long   0                         /* IsSync                               */
242         .long   32                        /* frame size                           */
243         .long   0                         /* method pointer (pointer to name)     */
244
245 asm_calljavafunction2:
246 asm_calljavafunction2double:
247 asm_calljavafunction2long:
248                 push    %ebp                  /* save ebp                             */
249
250                 mov     %esp,%eax             /* save stackptr                        */
251                 mov     20(%esp),%ebp
252
253         push    %ebx                  /* save registers                       */
254         push    %esi
255         push    %edi
256
257                 sub     $32,%esp
258
259         mov     sizejniblock*3+offjniitem+4(%ebp),%ebx
260         mov     %ebx,28(%esp)
261         mov     sizejniblock*3+offjniitem(%ebp),%ebx
262         mov     %ebx,24(%esp)
263
264         mov     sizejniblock*2+offjniitem+4(%ebp),%ebx
265         mov     %ebx,20(%esp)
266         mov     sizejniblock*2+offjniitem(%ebp),%ebx
267         mov     %ebx,16(%esp)
268
269
270         mov     sizejniblock+offjniitem+4(%ebp),%ebx
271         mov     %ebx,12(%esp)
272         mov     sizejniblock+offjniitem(%ebp),%ebx
273         mov     %ebx,8(%esp)
274
275         mov     offjniitem+4(%ebp),%ebx
276         mov     %ebx,4(%esp)
277         mov     offjniitem(%ebp),%ebx
278         mov     %ebx,0(%esp)
279
280                 mov     %eax,%ebp       
281                 mov     8(%ebp),%eax          /* move function pointer to %eax        */
282
283                 lea     asm_call_jit_compiler,%edx 
284                 call    *%edx                 /* call JIT compiler                    */
285         
286 calljava_return2:
287         add     $32,%esp
288         pop     %edi                  /* restore registers                    */
289         pop     %esi
290         pop     %ebx
291                 leave
292                 ret
293
294 calljava_xhandler2:
295                 push    %eax                              /* pass exception pointer               */
296                 call    builtin_throw_exception
297                 add     $4,%esp
298         
299                 add     $32,%esp
300         pop     %edi                  /* restore registers                    */
301         pop     %esi
302         pop     %ebx
303                 leave
304                 ret
305
306
307 /****************** function asm_call_jit_compiler *****************************
308 *                                                                              *
309 *   invokes the compiler for untranslated JavaVM methods.                      *
310 *                                                                              *
311 *   Register R0 contains a pointer to the method info structure (prepared      *
312 *   by createcompilerstub). Using the return address in R26 and the            *
313 *   offset in the LDA instruction or using the value in methodptr R28 the      *
314 *   patching address for storing the method address can be computed:           *
315 *                                                                              *
316 *   method address was either loaded using                                     *
317 *                                                                              *
318 *   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special       *
319 *   i386_call_reg(REG_ITMP2)                                                   *
320 *                                                                              *
321 *   or                                                                         *
322 *                                                                              *
323 *   i386_mov_membase_reg(REG_SP, 0, REG_ITMP1)    ; invokevirtual/interface    *
324 *   i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2)                *
325 *   i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \                *
326 *       sizeof(methodptr) * m->vftblindex, REG_ITMP1)                          *
327 *   i386_call_reg(REG_ITMP1)                                                   *
328 *                                                                              *
329 *   in the static case the method pointer can be computed using the            *
330 *   return address and the lda function following the jmp instruction          *
331 *                                                                              *
332 *******************************************************************************/
333
334
335 asm_call_jit_compiler:
336                 push    %ebx            /* save register                              */
337         push    %ebp
338                                 
339                 mov     8(%esp),%ebp    /* get return address (2 push)                */
340                 mov     -1(%ebp),%bl    /* get function code                          */
341                 cmp     $0xd1,%bl               /* called with `call *REG_ITMP2' (%ecx)?      */
342                 jne             L_not_static_special
343
344                 sub     $6,%ebp                 /* calculate address of immediate             */
345                 jmp             L_call_jit_compile
346                 
347 L_not_static_special:
348                 cmp     $0xd0,%bl               /* called with `call *REG_ITMP1' (%eax)       */
349                 jne             L_not_virtual_interface
350                 
351                 sub     $6,%ebp         /* calculate address of offset                */
352                 mov     (%ebp),%ebp     /* get offset                                 */
353                 add     %ecx,%ebp       /* add base address to get method address     */
354                 jmp             L_call_jit_compile
355
356 L_not_virtual_interface:        /* a call from asm_calljavafunction           */
357                 xor     %ebp,%ebp
358                 
359 L_call_jit_compile:
360                 push    %ebp            /* save address for method pointer            */
361
362                 push    %eax                    /* push methodpointer on stack                */
363                 call    jit_compile
364                 add     $4,%esp
365
366                 pop     %ebp            /* restore address for method pointer         */
367                 test    %ebp,%ebp               /* is address == 0 (asm_calljavafunction)     */
368                 je              L_call_method
369                 
370                 mov     %eax,(%ebp)             /* and now save the new pointer               */
371
372 L_call_method:
373         pop     %ebp            /* restore registers                          */
374                 pop     %ebx
375                         
376                 jmp             *%eax                   /* ...and now call the new method             */
377
378
379
380 /****************** function asm_dumpregistersandcall **************************
381 *                                                                              *
382 *   This funtion saves all callee saved registers and calls the function       *
383 *   which is passed as parameter.                                              *
384 *                                                                              *
385 *   This function is needed by the garbage collector, which needs to access    *
386 *   all registers which are stored on the stack. Unused registers are          *
387 *   cleared to avoid interferances with the GC.                                *
388 *                                                                              *
389 *   void asm_dumpregistersandcall (functionptr f);                             *
390 *                                                                              *
391 *******************************************************************************/
392
393 asm_dumpregistersandcall:
394         xor     %eax,%eax
395         mov     %eax,(%eax)
396
397                 push    %ebp
398         push    %ecx
399         push    %edx
400                 push    %ebx
401                 push    %esi
402                 push    %edi
403                                 
404                 mov     4(%ebp),%eax            /* load function pointer */
405                 call    *%eax                           /* call function */
406
407                 pop             %edi
408                 pop             %esi
409                 pop             %ebx
410         pop     %edx
411                 pop     %ecx
412                 pop             %ebp
413         
414                 ret
415         
416
417 /********************* function asm_handle_exception ***************************
418 *                                                                              *
419 *   This function handles an exception. It does not use the usual calling      *
420 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
421 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
422 *   the local exception table for a handler. If no one is found, it unwinds    *
423 *   stacks and continues searching the callers.                                *
424 *                                                                              *
425 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
426 *                                                                              *
427 *******************************************************************************/
428
429 asm_handle_builtin_exception:
430         add     $4,%esp                                         /* clear return address of this call */
431         mov     (%esp),%eax                 /* get exceptionptr               */
432         leave                               /* leave builtin function         */
433         mov     (%esp),%edx                 /* get exceptionpc                */
434         sub     $2,%edx                     /* size of builtin call           */
435         jmp     asm_handle_exception
436         
437 asm_handle_nat_exception:
438                 add     $4,%esp                                         /* clear return address of native stub */
439                 
440 asm_handle_exception:
441                 push    %ebp
442                 mov     %esp,%ebp
443         
444                 push    %eax                                            /* save exception pointer         */
445                 push    %ecx                        /* save exception pc              */
446
447 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
448                 call    cast_lock
449 #endif
450                 
451                 call    findmethod                  /* get the data segment ptr       */
452                 mov     %eax,%edx
453                         
454                 mov     -4(%ebp),%eax
455                 mov     -8(%ebp),%ecx               /* could be changed in findmethod */
456
457                 push    %edx                                            /* save data segment pointer      */
458                 push    %ebx
459                 push    %esi
460                 push    %edi
461                 
462 ex_stack_loop:
463                 sub     $16,%esp
464                 mov     %eax,(%esp)                                     /* exception pointer              */
465                 mov     MethodPointer(%edx),%eax        /* method pointer                 */
466                 mov     %eax,4(%esp)
467                 mov     %ecx,8(%esp)                            /* exception pc                   */
468                 movl    $1,12(%esp)                                     /* set no unwind flag             */
469                 call    builtin_trace_exception
470                 add     $16,%esp
471
472                 mov     -12(%ebp),%esi                          /* %esi = data segment pointer    */
473                 mov     ExTableSize(%esi),%ecx          /* %ecx = exception table size    */
474                 test    %ecx,%ecx                                       /* if empty table skip            */
475                 je      empty_table
476
477                 lea             ExTableStart(%esi),%edi         /* %edi = start of exception table*/
478                 mov     -4(%ebp),%eax               /* get xptr                       */
479                 
480 ex_table_loop:
481                 mov     -8(%ebp),%edx                           /* get xpc                        */
482
483                 mov     ExStartPC(%edi),%ebx            /* %ebx = exception start pc      */
484                 cmp     %edx,%ebx                                       /* %ebx = (startpc <= xpc)        */
485                 jg      ex_table_cont                           /* if (false) continue            */
486                 mov     ExEndPC(%edi),%ebx                      /* %ebx = exception end pc        */
487                 cmp     %ebx,%edx                                       /* %ebx = (xpc < endpc)           */
488                 jge     ex_table_cont                           /* if (false) continue            */
489                 mov     ExCatchType(%edi),%ebx          /* arg1 = exception catch type    */
490                 test    %ebx,%ebx                                       /* NULL catches everything        */
491                 je      ex_handle_it
492
493                 mov     offobjvftbl(%eax),%esi          /* %esi = vftblptr(xptr)          */
494                 mov     offclassvftbl(%ebx),%ebx    /* %ebx = vftblptr(catchtype) class (not obj) */
495                 mov     offbaseval(%esi),%esi           /* %esi = baseval(xptr)           */
496                 mov     offbaseval(%ebx),%edx           /* %edx = baseval(catchtype)      */
497                 mov     offdiffval(%ebx),%ebx           /* %ebx = diffval(catchtype)      */
498                 sub     %edx,%esi                                       /* %esi = baseval(xptr) - baseval(catchtype) */
499                 cmp     %ebx,%esi                                       /* xptr is instanceof catchtype   */
500                 ja      ex_table_cont
501                 
502 ex_handle_it:
503                 mov     ExHandlerPC(%edi),%edx
504                 
505                 pop     %edi                        /* restore registers              */
506                 pop     %esi
507                 pop     %ebx
508         add     $8,%esp                     /* suck %ecx, %edx                */
509         pop     %eax                        /* restore xptr                   */
510
511 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
512                 call cast_unlock
513 #endif
514         
515                 leave
516                 jmp             *%edx                       /* jump to exception handler      */
517
518 ex_table_cont:
519                 lea     ExEntrySize(%edi),%edi
520                 dec     %ecx
521                 test    %ecx,%ecx
522                 jg      ex_table_loop
523                 
524 empty_table:
525         pop     %edi
526         pop     %esi
527         pop     %ebx
528         pop     %edx                        /* restore data segment pointer   */
529         pop     %ecx
530         pop     %eax
531         pop     %ebp
532
533         push    %eax                        /* save exception pointer         */
534         
535 ex_already_cleared:
536                 mov     IsSync(%edx),%eax                       /* %eax = SyncOffset              */
537                 test    %eax,%eax                                       /* if zero no monitorexit         */
538                 je      no_monitor_exit
539
540         add     %esp,%eax
541         mov     -4(%eax),%eax               /* we have the xptr on the stack  */
542         push    %edx                        /* save regs                      */
543         push    %eax
544                 call    builtin_monitorexit
545                 add     $4,%esp
546         pop     %edx                        /* restore regs                   */
547         
548 no_monitor_exit:
549         mov     %esp,%eax
550         add     FrameSize(%edx),%eax        /* %eax = frame size              */
551         add     $4,%eax                     /* we have the xptr on the stack  */
552         
553                 mov     IntSave(%edx),%ecx          /* %ecx = saved int register count*/
554                 test    %ecx,%ecx
555                 je      noint
556                 cmp     $1,%ecx
557                 je      int1
558                 cmp     $2,%ecx
559                 je      int2
560                 cmp     $3,%ecx
561                 je      int3
562
563 int4:   
564                 mov     -32(%eax),%ebx
565
566 int3:   
567                 mov     -24(%eax),%ebp
568
569 int2:   
570                 mov     -16(%eax),%esi
571
572 int1:   
573                 mov     -8(%eax),%edi
574
575                 shl     $3,%ecx                                         /* multiply by 8 bytes             */
576                 sub     %ecx,%eax
577                 
578 noint:
579                 mov     FltSave(%edx),%ecx                      /* %ecx = saved flt register count */
580                 test    %ecx,%ecx
581                 je      noflt
582                 cmp     $1,%ecx
583                 je      flt1
584                 cmp     $2,%ecx
585                 je      flt2
586                 cmp     $3,%ecx
587                 je      flt3
588                 
589 flt4:   
590                 fldl    -32(%eax)
591                 fstp    %st(1)
592
593 flt3:   
594                 fldl    -24(%eax)
595                 fstp    %st(2)
596                 
597 flt2:   
598                 fldl    -16(%eax)
599                 fstp    %st(3)
600                 
601 flt1:   
602                 fldl    -8(%eax)
603                 fstp    %st(4)
604                 
605 noflt:
606         pop     %eax                        /* restore exception pointer      */
607         
608         mov     FrameSize(%edx),%ecx        /* %ecx = frame size              */
609         add     %ecx,%esp                   /* unwind stack                   */
610         
611                 pop     %ecx                        /* the new xpc is return address  */
612                 sub     $2,%ecx
613                 
614                 jmp             asm_handle_exception
615                 
616
617 /********************* function asm_check_clinit *******************************
618 *                                                                              *
619 *   Does null check and calls monitorenter or throws an exception              *
620 *                                                                              *
621 *******************************************************************************/
622
623 asm_check_clinit:
624                 mov             offclassinit(%eax),%ecx     /* get initialized flag           */
625                 test    %ecx,%ecx
626                 jnz             L_is_initialized
627
628                 push    %eax                        /* pass classinfo pointer         */
629                 call    class_init                  /* call class_init function       */
630                 add             $4,%esp
631                                 
632 L_is_initialized:
633                 mov             (%esp),%eax                 /* get return address             */
634                 sub             $12,%eax                    /* asm_putstatic call code size   */
635                 movb    $0xeb,(%eax)                /* jmp rel8                       */
636                 movl    $10,1(%eax)                 /* 32-bit offset                  */
637                 ret
638
639                 
640 /********************* function asm_builtin_monitorenter ***********************
641 *                                                                              *
642 *   Does null check and calls monitorenter or throws an exception              *
643 *                                                                              *
644 *******************************************************************************/
645
646 asm_builtin_monitorenter:
647                 cmpl    $0,4(%esp)
648                 je              nb_monitorenter                 /* if (null) throw exception          */
649                 jmp             builtin_monitorenter    /* else call builtin_monitorenter     */
650
651 nb_monitorenter:
652                 popl    %ecx                                    /* delete return address */
653                 subl    $2,%ecx                                 /* faulting address is return adress - 2 */
654                 movl    proto_java_lang_NullPointerException,%eax
655                 jmp             asm_handle_exception
656                 
657
658 /********************* function asm_builtin_monitorexit ************************
659 *                                                                              *
660 *   Does null check and calls monitorexit or throws an exception               *
661 *                                                                              *
662 *******************************************************************************/
663
664 asm_builtin_monitorexit:
665                 mov     4(%esp),%eax
666         test    %eax,%eax
667                 je      nb_monitorexit                  /* if (null) throw exception          */
668         push    %ecx                    /* save registers which could be used */
669         push    %edx
670         push    %eax
671                 call    builtin_monitorexit             /* else call builtin_monitorenter     */
672         add     $4,%esp
673         pop     %edx                    /* restore registers which could be used */
674         pop     %ecx
675         ret
676
677 nb_monitorexit:
678                 popl    %ecx                                    /* delete return address */
679                 subl    $2,%ecx                                 /* faulting address is return adress - 2 */
680                 movl    proto_java_lang_NullPointerException,%eax
681                 jmp             asm_handle_exception
682
683
684 /************************ function asm_builtin_ldiv ****************************
685 *                                                                              *
686 *   Does null check and calls ldiv or throws an exception                      *
687 *                                                                              *
688 *******************************************************************************/
689
690 asm_builtin_ldiv:
691                 mov             12(%esp),%eax
692                 or              16(%esp),%eax
693                 test    %eax,%eax                               /* if (null) throw exception */
694                 je              nb_ldiv
695
696                 jmp             builtin_ldiv
697
698 nb_ldiv:
699                 pop             %ecx                                    /* delete return address */
700                 sub             $2,%ecx                                 /* faulting address is return adress - 2 */
701                 mov             proto_java_lang_ArithmeticException,%eax
702                 jmp             asm_handle_exception
703                                 
704
705 /************************ function asm_builtin_lrem ****************************
706 *                                                                              *
707 *   Does null check and calls lrem or throws an exception                      *
708 *                                                                              *
709 *******************************************************************************/
710
711 asm_builtin_lrem:
712                 mov             12(%esp),%eax
713                 or                      16(%esp),%eax
714                 test    %eax,%eax                               /* if (null) throw exception */
715                 je              nb_lrem
716
717                 jmp             builtin_lrem
718
719 nb_lrem:
720                 pop             %ecx                                    /* delete return address */
721                 sub             $2,%ecx                                 /* faulting address is return adress - 2 */
722                 mov             proto_java_lang_ArithmeticException,%eax
723                 jmp             asm_handle_exception
724                 
725
726 /************************ function asm_builtin_x2x *****************************
727 *                                                                              *
728 *   Wrapper functions for corner cases                                         *
729 *                                                                              *
730 *******************************************************************************/
731
732 asm_builtin_f2i:
733         sub     $4,%esp
734         fsts    (%esp)
735         call    builtin_f2i
736         add     $4,%esp
737         ret             
738
739 asm_builtin_d2i:
740         sub     $8,%esp
741         fstl    (%esp)
742         call    builtin_d2i
743         add     $8,%esp
744         ret             
745
746 asm_builtin_f2l:
747         sub     $4,%esp
748         fsts    (%esp)
749         call    builtin_f2l
750         add     $4,%esp
751         ret             
752
753 asm_builtin_d2l:
754         sub     $8,%esp
755         fstl    (%esp)
756         call    builtin_d2l
757         add     $8,%esp
758         ret             
759
760         
761 /*********************** function new_builtin_checkcast ************************
762 *                                                                              *
763 *   Does the cast check and eventually throws an exception                     *
764 *                                                                              *
765 *******************************************************************************/
766
767 asm_builtin_checkcast:
768                 xor             %eax,%eax
769                 mov             %eax,(%eax)
770                 ret
771
772                 
773 /******************* function asm_builtin_checkarraycast ***********************
774 *                                                                              *
775 *   Does the cast check and eventually throws an exception                     *
776 *                                                                              *
777 *******************************************************************************/
778
779 asm_builtin_checkarraycast:
780                 sub             $8,%esp                                 /* build stack frame (2 * 4 bytes)    */
781
782                 mov             12(%esp),%eax           /* 8 (frame) + 4 (return)             */
783                 mov             %eax,(%esp)                             /* save object pointer                */
784
785                 mov             20(%esp),%eax
786                 mov             %eax,4(%esp)
787
788                 call    builtin_checkarraycast  /* builtin_checkarraycast             */
789         
790                 test    %eax,%eax               /* if (false) throw exception         */
791                 je              nb_carray_throw
792
793                 mov             12(%esp),%eax                   /* return object pointer              */
794                 add             $8,%esp
795                 ret
796
797 nb_carray_throw:
798                 add             $8,%esp
799                 
800                 pop             %ecx                                    /* delete return address              */
801                 sub             $2,%ecx                                 /* faulting address is return adress - 2 */
802                 mov             proto_java_lang_ClassCastException,%eax
803                 jmp             asm_handle_exception
804
805                 
806 /******************* function asm_builtin_newarray *****************************
807 *                                                                              *
808 *   Does the cast check and eventually throws an exception                     *
809 *                                                                              *
810 *******************************************************************************/
811
812 asm_builtin_newarray:
813                 sub             $8,%esp                                 /* build stack frame (2 * 4 bytes) */
814
815                 mov             12(%esp),%eax
816                 mov             %eax,(%esp)
817
818                 mov             20(%esp),%eax
819                 mov             %eax,4(%esp)
820
821                 call    builtin_newarray
822         
823                 add             $8,%esp
824                 ret
825
826                 
827 /******************* function asm_builtin_aastore ******************************
828 *                                                                              *
829 *   Does the cast check and eventually throws an exception                     *
830 *                                                                              *
831 *******************************************************************************/
832
833 asm_builtin_aastore:
834                 subl    $12,%esp                                /* build stack frame (3 * 4 bytes)    */
835
836                 movl    16(%esp),%eax           /* 12 (frame) + 4 (return)            */
837                 test    %eax,%eax                               /* if null pointer throw exception    */
838                 je              nb_aastore_null
839
840                 movl    offarraysize(%eax),%edx /* load size                          */
841                 movl    24(%esp),%ecx                   /* index                              */
842                 cmpl    %edx,%ecx                               /* do bound check                     */
843                 ja              nb_aastore_bound                /* if out of bounds throw exception   */
844
845                 shll    $2,%ecx                                 /* index * 4                          */
846                 addl    %eax,%ecx                               /* add index * 4 to arrayref          */
847                 
848                 movl    %ecx,8(%esp)                    /* save store position                */
849                 
850                 movl    16(%esp),%eax           /* 12 (frame) + 4 (return)            */
851                 movl    %eax,(%esp)
852
853                 movl    32(%esp),%eax                   /* object is second argument          */
854                 movl    %eax,4(%esp)
855                 
856                 call    builtin_canstore                /* builtin_canstore(arrayref,object)  */
857
858                 test    %eax,%eax                               /* if (false) throw exception         */
859                 je              nb_aastore_throw
860
861                 movl    32(%esp),%eax
862                 movl    8(%esp),%ecx
863                 movl    %eax,offobjarrdata(%ecx)/* store objectptr in array           */
864                 
865                 addl    $12,%esp
866                 ret
867
868 nb_aastore_null:
869                 addl    $12,%esp
870                 popl    %ecx                                    /* delete return address */
871                 subl    $2,%ecx                                 /* faulting address is return adress - 2 */
872                 movl    proto_java_lang_NullPointerException,%eax
873                 jmp             asm_handle_exception
874
875 nb_aastore_bound:
876                 addl    $12,%esp
877                 popl    %ecx                                    /* delete return address */
878                 subl    $2,%ecx                                 /* faulting address is return adress - 2 */
879                 movl    proto_java_lang_ArrayIndexOutOfBoundsException,%eax
880                 jmp             asm_handle_exception
881                 
882 nb_aastore_throw:
883                 addl    $12,%esp
884                 popl    %ecx                                    /* delete return address */
885                 subl    $2,%ecx                                 /* faulting address is return adress - 2 */
886                 movl    proto_java_lang_ArrayStoreException,%eax
887                 jmp             asm_handle_exception
888
889                 
890 /******************* function asm_builtin_arrayinstanceof **********************
891 *                                                                              *
892 *   Does the instanceof check of arrays                                        *
893 *                                                                              *
894 *******************************************************************************/
895
896 asm_builtin_arrayinstanceof:
897                 subl    $8,%esp                                 /* build stack frame (2 * 4 bytes) */
898
899                 movl    12(%esp),%eax
900                 movl    %eax,(%esp)
901
902                 movl    20(%esp),%eax
903                 movl    %eax,4(%esp)
904
905                 call    builtin_arrayinstanceof
906         
907                 addl    $8,%esp
908                 ret
909
910                 
911 /******************* function asm_initialize_thread_stack **********************
912 *                                                                              *
913 * initialized a thread stack                                                   *
914 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
915 *                                                                              *
916 *******************************************************************************/
917
918 asm_initialize_thread_stack:
919                 movl    8(%esp),%eax            /* (to)->stackEnd                     */
920                 subl    $36,%eax                                /* 4 bytes * 8 regs + 4 bytes func    */
921
922                 xorl    %edx,%edx
923                 movl    %edx,0(%eax)
924                 movl    %edx,4(%eax)
925                 movl    %edx,8(%eax)
926                 movl    %edx,12(%eax)
927                 movl    %edx,16(%eax)
928                 movl    %edx,20(%eax)
929                 movl    %edx,24(%eax)
930                 movl    %edx,28(%eax)
931
932                 movl    4(%esp),%edx            /* save (u1*) (func)                  */
933                 movl    %edx,32(%eax)
934
935                 ret                             /* return restorepoint in %eax        */
936
937
938 /******************* function asm_perform_threadswitch *************************
939 *                                                                              *
940 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
941 *                                                                              *
942 *   performs a threadswitch                                                    *
943 *                                                                              *
944 *******************************************************************************/
945
946 asm_perform_threadswitch:
947                 subl    $36,%esp
948
949                 movl    %eax,0(%esp)
950                 movl    %ecx,4(%esp)
951                 movl    %edx,8(%esp)
952                 movl    %ebx,12(%esp)
953                 movl    %esp,16(%esp)
954                 movl    %ebp,20(%esp)
955                 movl    %esi,24(%esp)
956                 movl    %edi,28(%esp)
957
958                 movl    36(%esp),%eax                   /* save current return address */
959                 movl    %eax,32(%esp)
960
961                 movl    40(%esp),%eax                   /* first argument **from */
962                 movl    %esp,0(%eax)
963
964                 movl    48(%esp),%eax                   /* third argument **stackTop */
965                 movl    %esp,0(%eax)
966
967                 movl    44(%esp),%eax                   /* second argument **to */
968                 movl    0(%eax),%esp                    /* load new stack pointer */
969
970                 movl    0(%esp),%eax
971                 movl    4(%esp),%ecx
972                 movl    8(%esp),%edx
973                 movl    12(%esp),%ebx
974                                                                                 /* skip stack pointer */
975                 movl    20(%esp),%ebp
976                 movl    24(%esp),%esi
977                 movl    28(%esp),%edi
978
979                 addl    $32,%esp                /* leave return address on stack      */
980                 ret
981                 
982
983 /********************* function asm_switchstackandcall *************************
984 *                                                                              *
985 *  int asm_switchstackandcall (void *stack, void *func, void **stacktopsave,   *
986 *                                      void *p);                                       *
987 *                                                                              *
988 *   Switches to a new stack, calls a function and switches back.               *
989 *       a0      new stack pointer                                              *
990 *       a1      function pointer                                               *
991 *               a2              pointer to variable where stack top should be stored           *
992 *       a3      pointer to user data, is passed to the function                *
993 *                                                                              *
994 *******************************************************************************/
995
996 asm_switchstackandcall:
997                 movl    4(%esp),%edx                    /* first argument *stack              */
998                 subl    $8,%edx                                 /* allocate new stack                 */
999
1000                 movl    (%esp),%eax                             /* save return address on new stack   */
1001                 movl    %eax,(%edx)
1002
1003                 movl    %esp,4(%edx)                    /* save old stack pointer on new stack*/
1004
1005                 movl    12(%esp),%eax                   /* third argument **stacktopsave      */
1006                 movl    %esp,(%eax)                             /* save old stack pointer to variable */
1007
1008                 movl    8(%esp),%eax                    /* load function pointer              */
1009                 movl    16(%esp),%ecx                   /* fourth argument *p                 */
1010                 
1011                 movl    %edx,%esp                               /* switch to new stack                */
1012
1013                 subl    $4,%esp
1014                 movl    %ecx,0(%esp)                    /* pass pointer                       */
1015                 call    *%eax                                   /* and call function                  */
1016                 addl    $4,%esp
1017
1018                 movl    (%esp),%edx                             /* load return address                */
1019                 movl    4(%esp),%esp                    /* switch to old stack                */
1020                 movl    %edx,(%esp)
1021                 ret
1022
1023                 
1024 /********************* function asm_getcallingmethod ***************************
1025 *                                                                              *
1026 *   classinfo *asm_getcallingmethod ();                                                                    *
1027 *                                                                                                                                                          *    
1028 *   goes back stack frames to get the calling method                                               *       
1029 *                                                                                                                                                          *    
1030 *                               t2 .. sp                                                                                                       *
1031 *                               t3 .. ra                                                                                                       *
1032 *                               t4 .. pv                                                                                                       *
1033 *                                                                              *
1034 *******************************************************************************/
1035
1036 asm_getcallingmethod:
1037                 xorl    %eax,%eax
1038 /*              movl    $0,(%eax) */
1039                 ret
1040
1041 Java_java_lang_VMSecurityManager_currentClassLoader:
1042         lea  builtin_asm_getclassloader,%eax 
1043         push %eax       /*store collector function pointer*/
1044         jmp getClassContext_begin
1045 Java_java_lang_VMSecurityManager_getClassContext:
1046         lea  builtin_asm_createclasscontextarray,%eax 
1047         push %eax /*store collector function pointer*/
1048 getClassContext_begin:  /*start the real work*/
1049 /* find the method calling this */
1050         mov %esp,%eax
1051         sub $4,%eax
1052         sub $68,%esp /*64 memory location without overwriting return adress and collector function adress*/
1053         mov %esp,%ebx   /*end of allocated memory block for classpointers is the adress of the working data block +4 */
1054         push $0 /*%esp+32 was native*/
1055         push %eax /*%esp+24 blkbegin*/
1056         push %eax /*%esp+20 currentpos*/
1057         push %ebx /*%esp+16 blkend*/
1058
1059         call builtin_asm_get_threadrootmethod
1060         push %eax /*%esp+12*/
1061         movl 104(%esp),%eax /*(stack contains: threadRootMethod,blkend,blkpos,blkbegin,was native, data(64kB),collector,ret,env,class,frame stack info of stub, we want the frame stack info  of thestub*/
1062         movl %esp,%edx
1063         addl $104, %edx
1064         push %edx /*esp+8*/ /*position of return address of native stub*/
1065         call builtin_asm_get_framestackinfo
1066         push %eax /*esp+4*/ /*address of frame info block*/
1067         movl  offreturnfromnative(%eax),%edx
1068         movl  offprevnative(%eax),%ebx
1069         mov  %ebx,(%esp)
1070         push %edx /*esp+0*/ /*return adress out of native stub*/
1071         call findmethod /*find calling java method, this one is still to be skipped (==SecurityManager.getClassContext (or .currentClassLoader)*/
1072
1073
1074         mov 8(%esp),%ebx /*pos of return adress */
1075         add FrameSize(%eax),%ebx
1076         add $4,%ebx     /*adress of new return adress (out of Securitymanager.*/
1077         mov %ebx,8(%esp) 
1078         mov %eax,(%esp)
1079
1080         /* by now we have skipped this method call and the one before (SecurityManager)*/
1081
1082 getClassContext_next:   
1083         movl 8(%esp),%eax
1084         movl (%eax),%eax
1085         movl %eax,(%esp) /*return adress*/
1086
1087         call findmethod
1088
1089         cmp $1,32(%esp)
1090         je getClassContext_storeNextRetPrevWasNat
1091         mov 8(%esp),%ebx
1092         add FrameSize(%eax),%ebx
1093         add $4,%ebx
1094         mov %ebx,8(%esp) /*store adress of next return adress*/
1095 getClassContext_nextRetStored:
1096
1097         mov MethodPointer(%eax),%ecx    /*get struct methodinfo*/
1098
1099         cmp $0,%ecx
1100         je getClassContext_nativeCall
1101         /*save class pointer*/
1102         movl $0,32(%esp)
1103 getClassContext_saveClassPointer:
1104         movl 20(%esp),%ebx      /*get temporary memory adress in stack*/
1105         movl offclassmethodinfo(%ecx),%edx /* get class pointer of method*/
1106         movl %edx,(%ebx) /*save */
1107         sub $4,%ebx     /*calculate next position */
1108         movl %ebx,20(%esp) /* check if the new adress would overwrite our working data */
1109         cmp %ebx,16(%esp)
1110         je getClassContext_incStack
1111 getClassContext_checkLeave:
1112         
1113         cmp 12(%esp),%ecx       /*check if we reached the toplevel method of our thread*/
1114         je  getClassContext_leave /*yes ->leave*/
1115
1116         mov %ecx,(%esp)
1117         call temporaryGetClassContextHelper
1118         
1119         
1120         jmp getClassContext_next /*continue*/
1121
1122 getClassContext_storeNextRetPrevWasNat:
1123         movl 8(%esp),%ebx
1124         add $(offaddrreturnfromnative-offreturnfromnative),%ebx
1125         movl (%ebx),%ebx
1126         add FrameSize(%eax),%ebx
1127         add $4,%ebx
1128         movl %ebx,8(%esp) /*store adress of next return adress*/
1129         jmp getClassContext_nextRetStored
1130
1131 getClassContext_nativeCall:
1132         movl $1,32(%esp)
1133         movl 4(%esp),%eax
1134         movl %eax,%ebx
1135         addl $offreturnfromnative,%ebx
1136         /*offreturnfromnative(%eax)+returnFromNativeoffset,%ebx*/
1137         movl %ebx,8(%esp)
1138         movl offmethodnative(%eax),%ecx
1139         movl offprevnative(%eax),%edx
1140         movl %edx,4(%esp)
1141         jmp getClassContext_saveClassPointer
1142
1143 getClassContext_incStack:
1144         /*make another 64 kb in our temporary storage free and store the workingdata */
1145         movl %esp,%edx
1146         subl $40,%esp /*should be 32*/
1147         push 32(%edx)
1148         push 28(%edx)
1149         push 24(%edx)
1150         push 20(%edx)
1151         push 16(%edx)
1152         push 12(%edx)
1153         push 8(%edx)
1154         push 4(%edx)
1155         push 0(%edx)
1156         subl $64,16(%esp)
1157
1158         jmp getClassContext_checkLeave /* continue */
1159
1160 getClassContext_leave:
1161         mov %ecx,(%esp)
1162         call temporaryGetClassContextHelper
1163
1164         /*call collector function with begin/end of temporary classarray*/
1165         push 24(%esp)
1166         push 24(%esp)
1167         
1168         movl 32(%esp),%eax
1169         add $4,%eax
1170         movl (%eax),%ebx
1171         call *%ebx
1172
1173         /* free stack memory of this function*/
1174         mov 32(%esp),%esp
1175         add $8,%esp
1176         ret
1177
1178 /*
1179  * These are local overrides for various environment variables in Emacs.
1180  * Please do not remove this and leave it at the end of the file, where
1181  * Emacs will automagically detect them.
1182  * ---------------------------------------------------------------------
1183  * Local variables:
1184  * mode: asm
1185  * indent-tabs-mode: t
1186  * c-basic-offset: 4
1187  * tab-width: 4
1188  * End:
1189  */