1 /* src/vm/jit/powerpc/asmpart.S - Java-C interface functions for PowerPC
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software.text; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY ; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
31 Changes: Christian Thalinger
33 $Id: asmpart.S 2525 2005-05-24 10:28:20Z twisti $
38 #if defined(__LINUX__)
39 # include <asm/ppc_asm.h>
43 #include "vm/jit/powerpc/offsets.h"
44 #include "vm/jit/powerpc/asmoffsets.h"
47 #if defined(__DARWIN__)
82 #endif /* defined(__DARWIN__) */
85 /* register defines ***********************************************************/
172 /* save and restore macros ****************************************************/
174 #define SAVE_ARGUMENT_REGISTERS(off) \
175 stw a0,(0+(off))*4(sp); \
176 stw a1,(1+(off))*4(sp); \
177 stw a2,(2+(off))*4(sp); \
178 stw a3,(3+(off))*4(sp); \
179 stw a4,(4+(off))*4(sp); \
180 stw a5,(5+(off))*4(sp); \
181 stw a6,(6+(off))*4(sp); \
182 stw a7,(7+(off))*4(sp); \
184 stfd fa0,(8+(off))*4)(sp); \
185 stfd fa1,(10+(off))*4)(sp); \
186 stfd fa2,(12+(off))*4)(sp); \
187 stfd fa3,(14+(off))*4)(sp); \
188 stfd fa4,(16+(off))*4)(sp); \
189 stfd fa5,(18+(off))*4)(sp); \
190 stfd fa6,(20+(off))*4)(sp); \
191 stfd fa7,(22+(off))*4)(sp); \
192 stfd fa8,(24+(off))*4)(sp); \
193 stfd fa9,(26+(off))*4)(sp); \
194 stfd fa10,(28+(off))*4)(sp); \
195 stfd fa11,(30+(off))*4)(sp); \
196 stfd fa12,(32+(off))*4)(sp);
198 #define RESTORE_ARGUMENT_REGISTERS(off) \
199 lwz a0,(0+(off))*4(sp); \
200 lwz a1,(1+(off))*4(sp); \
201 lwz a2,(2+(off))*4(sp); \
202 lwz a3,(3+(off))*4(sp); \
203 lwz a4,(4+(off))*4(sp); \
204 lwz a5,(5+(off))*4(sp); \
205 lwz a6,(6+(off))*4(sp); \
206 lwz a7,(7+(off))*4(sp); \
208 lfd fa0,(8+(off))*4)(sp); \
209 lfd fa1,(10+(off))*4)(sp); \
210 lfd fa2,(12+(off))*4)(sp); \
211 lfd fa3,(14+(off))*4)(sp); \
212 lfd fa4,(16+(off))*4)(sp); \
213 lfd fa5,(18+(off))*4)(sp); \
214 lfd fa6,(20+(off))*4)(sp); \
215 lfd fa7,(22+(off))*4)(sp); \
216 lfd fa8,(24+(off))*4)(sp); \
217 lfd fa9,(26+(off))*4)(sp); \
218 lfd fa10,(28+(off))*4)(sp); \
219 lfd fa11,(30+(off))*4)(sp); \
220 lfd fa12,(32+(off))*4)(sp);
223 #if defined(__DARWIN__)
225 /* Defines for darwin's old gnu assembler *************************************/
227 /* internal defines ***********************************************************/
229 #define asm_calljavafunction _asm_calljavafunction
230 #define asm_calljavafunction_int _asm_calljavafunction_int
232 #define asm_calljavafunction2 _asm_calljavafunction2
233 #define asm_calljavafunction2int _asm_calljavafunction2int
234 #define asm_calljavafunction2long _asm_calljavafunction2long
235 #define asm_calljavafunction2float _asm_calljavafunction2float
236 #define asm_calljavafunction2double _asm_calljavafunction2double
238 #define asm_call_jit_compiler _asm_call_jit_compiler
240 #define asm_handle_nat_exception _asm_handle_nat_exception
241 #define asm_handle_exception _asm_handle_exception
242 #define asm_handle_nullptr_exception _asm_handle_nullptr_exception
244 #define asm_wrapper_patcher _asm_wrapper_patcher
246 #define asm_builtin_arraycheckcast _asm_builtin_arraycheckcast
247 #define asm_builtin_aastore _asm_builtin_aastore
249 #define asm_builtin_monitorenter _asm_builtin_monitorenter
250 #define asm_builtin_monitorexit _asm_builtin_monitorexit
252 #define asm_builtin_idiv _asm_builtin_idiv
253 #define asm_builtin_irem _asm_builtin_irem
254 #define asm_builtin_ldiv _asm_builtin_ldiv
255 #define asm_builtin_lrem _asm_builtin_lrem
257 #define asm_cacheflush _asm_cacheflush
258 #define asm_initialize_thread_stack _asm_initialize_thread_stack
259 #define asm_perform_threadswitch _asm_perform_threadswitch
260 #define asm_switchstackandcall _asm_switchstackandcall
261 #define asm_criticalsections _asm_criticalsections
262 #define asm_getclassvalues_atomic _asm_getclassvalues_atomic
265 /* external defines ***********************************************************/
267 #define builtin_asm_get_exceptionptrptr _builtin_asm_get_exceptionptrptr
268 #define builtin_canstore _builtin_canstore
269 #define builtin_arraycheckcast _builtin_arraycheckcast
270 #define builtin_ldiv _builtin_ldiv
271 #define builtin_lrem _builtin_lrem
273 #if defined(USE_THREADS)
274 #define builtin_monitorenter _builtin_monitorenter
275 #define builtin_monitorexit _builtin_monitorexit
278 #define builtin_throw_exception _builtin_throw_exception
279 #define builtin_trace_exception _builtin_trace_exception
280 #define initialize_class _initialize_class
281 #define link_class _link_class
282 #define load_class_bootstrap _load_class_bootstrap
283 #define jit_compile _jit_compile
284 #define new_arithmeticexception _new_arithmeticexception
285 #define new_arrayindexoutofboundsexception _new_arrayindexoutofboundsexception
286 #define new_arraystoreexception _new_arraystoreexception
287 #define new_classcastexception _new_classcastexception
288 #define new_nullpointerexception _new_nullpointerexception
290 #if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
292 #define _exceptionptr __exceptionptr
296 .globl __exceptionptr
299 #endif /* defined(__DARWIN__) */
306 .globl asm_calljavafunction
307 .globl asm_calljavafunction_int
309 .globl asm_calljavafunction2
310 .globl asm_calljavafunction2int
311 .globl asm_calljavafunction2long
312 .globl asm_calljavafunction2float
313 .globl asm_calljavafunction2double
315 .globl asm_call_jit_compiler
317 .globl asm_handle_nat_exception
318 .globl asm_handle_exception
319 .globl asm_handle_nullptr_exception
321 .globl asm_wrapper_patcher
323 .globl asm_builtin_arraycheckcast
324 .globl asm_builtin_aastore
326 #if defined(USE_THREADS)
327 .globl asm_builtin_monitorenter
328 .globl asm_builtin_monitorexit
331 .globl asm_builtin_idiv
332 .globl asm_builtin_irem
333 .globl asm_builtin_ldiv
334 .globl asm_builtin_lrem
336 .globl asm_cacheflush
337 .globl asm_initialize_thread_stack
338 .globl asm_perform_threadswitch
339 .globl asm_switchstackandcall
340 .globl asm_criticalsections
341 .globl asm_getclassvalues_atomic
344 /********************* function asm_calljavafunction ***************************
346 * This function calls a Java-method (which possibly needs compilation) *
347 * with up to 4 address parameters. *
349 * This functions calls the JIT-compiler which eventually translates the *
350 * method into machine code. *
353 * javaobject_header *asm_calljavamethod (methodinfo *m, *
354 * void *arg1, void *arg2, void *arg3, void *arg4); *
356 *******************************************************************************/
360 .long 0 /* catch type all */
361 .long calljava_xhandler /* handler pc */
362 .long calljava_xhandler /* end pc */
363 .long asm_calljavafunction /* start pc */
364 .long 1 /* extable size */
365 .long 0 /* fltsave */
366 .long 0 /* intsave */
369 .long 24 /* frame size */
370 .long 0 /* method pointer (pointer to name) */
371 .long 0 /* padding */
373 asm_calljavafunction:
374 asm_calljavafunction_int:
410 #if defined(__DARWIN__)
411 /* addis mptr,r31,ha16(_asm_call_jit_compiler-0b)*/
412 addi mptr,r31,lo16(asm_call_jit_compiler-0b)
414 addi mptr,r31,(asm_call_jit_compiler-0b)@l
425 #if defined(__DARWIN__)
426 addi pv,itmp1,lo16(asm_calljavafunction-1b)
428 addi pv,itmp1,(asm_calljavafunction-1b)@l
459 bl builtin_throw_exception
460 b calljava_regrestore
467 .long 0 /* catch type all */
468 .long calljava_xhandler2 /* handler pc */
469 .long calljava_xhandler2 /* end pc */
470 .long asm_calljavafunction2 /* start pc */
471 .long 1 /* extable size */
472 .long 0 /* fltsave */
473 .long 0 /* intsave */
476 .long 24 /* frame size */
477 .long 0 /* method pointer (pointer to name) */
478 .long 0 /* padding */
480 asm_calljavafunction2:
481 asm_calljavafunction2int:
482 asm_calljavafunction2long:
483 asm_calljavafunction2float:
484 asm_calljavafunction2double:
512 stw r3,36(r1) /* save method pointer for compiler */
513 mr itmp1,r6 /* pointer to arg block */
514 mr itmp2,r4 /* arg count */
517 ble calljava_argsloaded
520 lwz r3,offjniitem+4(itmp1)
522 ble calljava_argsloaded
525 lwz r4,offjniitem+sizejniblock*1+4(itmp1)
527 ble calljava_argsloaded
531 lwz r5,offjniitem+sizejniblock*2+4(itmp1)
533 ble calljava_argsloaded
537 lwz r6,offjniitem+sizejniblock*3+4(itmp1)
539 ble calljava_argsloaded
544 #if defined(__DARWIN__)
545 /* addis mptr,r31,ha16(_asm_call_jit_compiler-0b)*/
546 addi mptr,r31,lo16(asm_call_jit_compiler-0b)
548 addi mptr,r31,(asm_call_jit_compiler-0b)@l
558 #if defined(__DARWIN__)
559 addi pv,itmp1,lo16(asm_calljavafunction2-1b)
561 addi pv,itmp1,(asm_calljavafunction2-1b)@l
564 calljava_regrestore2:
592 bl builtin_throw_exception
593 b calljava_regrestore2
596 asm_call_jit_compiler:
690 /***************** function asm_handle_nullptr_exception ***********************
692 * This behaves the same as asm_handle_exception but calls *
693 * new_nullpointerexception first *
695 *******************************************************************************/
697 asm_handle_nullptr_exception:
700 bl new_nullpointerexception
704 b asm_handle_exception
706 /********************* function asm_handle_exception ***************************
708 * This function handles an exception. It does not use the usual calling *
709 * conventions. The exception pointer is passed in REG_ITMP1 and the *
710 * pc from the exception raising position is passed in REG_ITMP2. It searches *
711 * the local exception table for a handler. If no one is found, it unwinds *
712 * stacks and continues searching the callers. *
714 * void asm_handle_exception (exceptionptr, exceptionpc); *
716 *******************************************************************************/
718 asm_handle_nat_exception:
726 bne asm_handle_exception
731 asm_handle_exception:
761 lwz r3,0*4(r1) /* exception pointer */
762 lwz r4,MethodPointer(pv) /* method pointer */
763 mr r5,xpc /* exception pc */
765 li r6,0 /* line number */
766 li r7,4 /* set no unwind flag */
768 /* XXX no valid stack frame chaining here */
769 addi r1,r1,-(24+5*4) /* 24 linkage area + 5 argument * 4 */
770 bl builtin_trace_exception
775 lwz xptr,0*4(r1) /* restore xptr */
780 lwz r3,ExTableSize(pv) /* r3 = exception table size */
781 mr. r3,r3 /* if empty table skip */
784 addi r4,pv,ExTableStart /* r4 = start of exception table */
787 lwz r5,ExStartPC(r4) /* r5 = exception start pc */
788 cmplw r5,xpc /* (startpc <= xpc) */
790 lwz r5,ExEndPC(r4) /* r5 = exception end pc */
791 cmplw xpc,r5 /* (xpc < endpc) */
793 lwz r7,ExCatchType(r4) /* r7 = exception catch type */
797 lwz itmp3,offclassloaded(r7)
801 /* XXX no valid stack frame chaining here */
802 addi r1,r1,-16*4 /* allocate stack */
803 stw r3,7*4(r1) /* save used registers */
804 stw r4,8*4(r1) /* 6*4 (linkage) + 1*4 (arg1) + 7*4 (save) */
812 mr r3,r7 /* arg1 = exceptionclass */
813 bl load_class_bootstrap
826 lwz itmp3,offclasslinked(r7)
828 /* XXX no valid stack frame chaining here */
829 addi r1,r1,-16*4 /* allocate stack */
833 stw r3,7*4(r1) /* save used registers */
834 stw r4,8*4(r1) /* 6*4 (linkage) + 1*4 (arg1) + 7*4 (save) */
841 mr r3,r7 /* arg1 = exceptionclass */
856 lwz r6,offobjvftbl(xptr) /* r6 = vftblptr(xptr) */
857 lwz r7,offclassvftbl(r7) /* r7 = vftblptr(catchtype) class (not obj) */
858 lwz r6,offbaseval(r6) /* r6 = baseval(xptr) */
859 lwz r8,offbaseval(r7) /* r8 = baseval(catchtype) */
860 lwz r7,offdiffval(r7) /* r7 = diffval(catchtype) */
862 subf r6,r8,r6 /* r6 = baseval(xptr) - baseval(catchtype) */
863 cmplw r6,r7 /* xptr is instanceof catchtype */
865 bgt ex_table_cont /* if (false) continue */
868 lwz xpc,ExHandlerPC(r4) /* xpc = exception handler pc */
897 addi r4,r4,ExEntrySize
902 mr. r9,r9 /* if here the first time, then */
903 beq ex_already_cleared
904 addi r1,r1,18*4 /* deallocate stack and */
905 li r9,0 /* clear the no unwind flag */
911 #if defined(USE_THREADS)
925 /* XXX no valid stack frame chaining here */
927 bl builtin_monitorexit
941 lwz r3,FrameSize(pv) /* r3 = frame size */
942 add r1,r1,r3 /* unwind stack */
943 mr r3,r1 /* r3 = pointer to save area */
944 lwz r4,IsLeaf(pv) /* r4 = is leaf procedure */
946 bne ex_no_restore /* if (leaf) skip */
947 lwz r4,8(r3) /* restore ra */
950 mflr r4 /* the new xpc is ra */
952 lwz r4,IntSave(pv) /* r4 = saved int register count */
956 #if defined(__DARWIN__)
957 addi r5,r5,lo16(ex_int2-ex_int1)
959 addi r5,r5,(ex_int2-ex_int1)@l
982 #if defined(__DARWIN__)
983 addi r5,r5,lo16(ex_flt2-ex_flt1)
985 addi r5,r5,(ex_flt2-ex_flt1)@l
1016 /* asm_wrapper_patcher *********************************************************
1021 16 return address into JIT code (patch position)
1022 12 pointer to virtual java_objectheader
1023 8 machine code (which is patched back later)
1024 4 unresolved class/method/field reference
1025 0 patcher function pointer to call
1027 *******************************************************************************/
1029 asm_wrapper_patcher:
1030 lwz itmp2,offclassinit(itmp1)
1032 bne L_is_initialized
1035 #if defined(__DARWIN__)
1040 stwu r1,-(36*8)(r1) /* keep stack 16-bytes aligned */
1043 stw r3,4*8(r1) /* save argument registers */
1044 stw r4,5*8(r1) /* preserve linkage area (24 bytes) */
1045 stw r5,6*8(r1) /* and 4 bytes (better 8) for 1 argument */
1066 SAVE_ARGUMENT_REGISTERS(6+1) /* save 8 int/13 float argument registers */
1083 mr itmp1,r3 /* save return value in temp register */
1109 RESTORE_ARGUMENT_REGISTERS(6+1)/* restore 8 int/13 float argument reg. */
1128 mr. itmp1,itmp1 /* check for an exception */
1129 beq L_initializererror
1135 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1138 stwu r1,-4*8(r1) /* preserve linkage area (24 bytes) */
1139 bl builtin_asm_get_exceptionptrptr
1144 # if defined(__DARWIN__)
1145 lwz r3,lo16(_exceptionptr-0b)(pv)
1147 lis r3,_exceptionptr@ha
1148 addi r3,r3,_exceptionptr@l
1152 lwz xptr,0(r3) /* get the exception pointer */
1154 stw r0,0(r3) /* clear the exception pointer */
1157 b asm_handle_nat_exception
1160 /* asm_builtin_arraycheckcast **************************************************
1162 Does the cast check and eventually throws an exception.
1164 *******************************************************************************/
1166 asm_builtin_arraycheckcast:
1172 bl builtin_arraycheckcast
1187 bl new_classcastexception
1193 b asm_handle_nat_exception
1196 /******************* function asm_builtin_aastore ******************************
1198 * Does the cast check and eventually throws an exception *
1200 *******************************************************************************/
1202 asm_builtin_aastore:
1209 lwz itmp1,offarraysize(r3)
1213 bge nb_aastore_bound
1225 beq nb_aastore_store
1226 stw itmp2,offobjarrdata(itmp1)
1233 bl new_nullpointerexception
1239 b asm_handle_nat_exception
1245 stwu r1,-(24+1*4)(r1)
1246 mr r3,r4 /* move index into a0 */
1247 bl new_arrayindexoutofboundsexception
1253 b asm_handle_nat_exception
1259 bl new_arraystoreexception
1265 b asm_handle_nat_exception
1268 #if defined(USE_THREADS)
1269 asm_builtin_monitorenter:
1272 b builtin_monitorenter
1278 bl new_nullpointerexception
1282 /* addi xpc,r0,-4 */
1286 b asm_handle_nat_exception
1289 asm_builtin_monitorexit:
1292 b builtin_monitorexit
1298 bl new_nullpointerexception
1302 /* addi xpc,r0,-4 */
1306 b asm_handle_nat_exception
1328 bl new_arithmeticexception
1334 b asm_handle_nat_exception
1351 mullw itmp3,itmp3,r4
1359 bl new_arithmeticexception
1365 b asm_handle_nat_exception
1377 bl new_arithmeticexception
1383 b asm_handle_nat_exception
1395 bl new_arithmeticexception
1401 b asm_handle_nat_exception
1434 asm_initialize_thread_stack:
1464 #if defined(__DARWIN__)
1465 lfd fr0,lo16(doublezero-0b)(r3)
1467 lfd fr0,(doublezero-0b)@l(r3)
1494 asm_perform_threadswitch:
1586 asm_switchstackandcall:
1604 asm_getclassvalues_atomic:
1607 lwz r6,offbaseval(r3)
1608 lwz r7,offdiffval(r3)
1609 lwz r8,offbaseval(r4)
1611 stw r6,offcast_super_baseval(r5)
1612 stw r7,offcast_super_diffval(r5)
1613 stw r8,offcast_sub_baseval(r5)
1618 asm_criticalsections:
1619 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1622 .long _crit_restart1
1625 .long _crit_restart2
1631 * These are local overrides for various environment variables in Emacs.
1632 * Please do not remove this and leave it at the end of the file, where
1633 * Emacs will automagically detect them.
1634 * ---------------------------------------------------------------------
1637 * indent-tabs-mode: t