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