src/vm/jit/powerpc64/asmpart.S
author Stefan Ring <stefan@complang.tuwien.ac.at>
Mon, 06 Jul 2009 17:16:20 +0200
changeset 9206 64ad75e2087e
parent 7701 d992be0f02d6
child 9393 4e21d1156405
permissions -rw-r--r--
i386 / x86_64: Align patcher trap instruction.
* src/vm/jit/i386/emit.c: Added emit_patcher_alignment.
* src/vm/jit/x86_64/emit.c: Likewise.
* src/vm/jit/i386/md-trap.h: Added emit_patcher_alignment, defined
ALIGN_PATCHER_TRAP.
* src/vm/jit/x86_64/md-trap.h: Likewise.
* src/vm/jit/patcher-common.cpp (patcher_add_patch_ref): Use
emit_patcher_alignment if requested.
     1 /* src/vm/jit/powerpc64/asmpart.S - Java-C interface functions for PowerPC64
     2 		
     3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
     4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
     5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
     6    J. Wenninger, Institut f. Computersprachen - TU Wien
     7 
     8    This file is part of CACAO.
     9 
    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.
    14 
    15    This program is distributed in the hope that it will be useful, but
    16    WITHOUT ANY WARRANTY	;  without even the implied warranty of
    17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    18    General Public License for more details.
    19 
    20    You should have received a copy of the GNU General Public License
    21    along with this program;  if not, write to the Free Software
    22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    23    02110-1301, USA.
    24 
    25 */
    26 
    27 
    28 #include "config.h"
    29 
    30 #define __ASSEMBLY__
    31 
    32 #include "md-abi.h"
    33 #include "md-asm.h"
    34 
    35 #include "vm/jit/abi-asm.h"
    36 #include "vm/jit/methodheader.h"
    37 
    38 
    39 /* export functions ***********************************************************/
    40 
    41 	.globl asm_vm_call_method_exception_handler
    42 	.globl asm_vm_call_method_end
    43 
    44 	.globl asm_handle_nat_exception
    45 	.globl asm_handle_exception
    46 
    47 	.globl asm_abstractmethoderror
    48 
    49 	.globl asm_cacheflush
    50 
    51 
    52 /* asm_vm_call_method **********************************************************
    53 *                                                                              *
    54 *   This function calls a Java-method (which possibly needs compilation)       *
    55 *   with up to 4 address parameters.                                           *
    56 *                                                                              *
    57 *   This functions calls the JIT-compiler which eventually translates the      *
    58 *   method into machine code.                                                  *
    59 *                                                                              *
    60 *   C-prototype:                                                               *
    61 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
    62 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
    63 *                                                                              *
    64 *******************************************************************************/
    65 	/* this is the method header see src/vm/jit/methodheader.h */
    66 
    67 	.align	3
    68 
    69 	.long   0                           /* fltsave                            */
    70 	.long   0                           /* intsave                            */
    71 	.long   0                           /* isleaf                             */
    72 	.long   0                           /* frame size                         */
    73 	.quad   0                           /* codeinfo pointer                   */
    74 
    75 #ifdef ENABLE_LIBJVM
    76 	
    77 	.globl asm_vm_call_method
    78 	.globl asm_vm_call_method_int
    79 	.globl asm_vm_call_method_long
    80 	.globl asm_vm_call_method_float
    81 	.globl asm_vm_call_method_double
    82 	.section ".opd","aw"
    83 	.align 3
    84 
    85 	asm_vm_call_method:
    86 	asm_vm_call_method_int:
    87 	asm_vm_call_method_long:
    88 	asm_vm_call_method_float:
    89 	asm_vm_call_method_double:
    90 		.quad	.asm_vm_call_method,.TOC.@tocbase,0
    91 		.previous
    92 		.size asm_vm_call_method, 24
    93 		.type .asm_vm_call_method,@function
    94 		.globl .asm_vm_call_method
    95 #else
    96 	asm_vm_call_method:
    97 	.globl asm_vm_call_method
    98 	asm_vm_call_method_int:
    99 	.globl asm_vm_call_method_int
   100 	asm_vm_call_method_long:
   101 	.globl asm_vm_call_method_long
   102 	asm_vm_call_method_float:
   103 	.globl asm_vm_call_method_float
   104 	asm_vm_call_method_double:
   105 	.globl asm_vm_call_method_double
   106 #endif
   107 
   108 .asm_vm_call_method:
   109 .asm_vm_call_method_int:
   110 .asm_vm_call_method_long:
   111 .asm_vm_call_method_float:
   112 .asm_vm_call_method_double:
   113 	mflr    r0
   114 	std     r0,LA_LR_OFFSET(sp)
   115 	stdu    sp,-40*8(sp)
   116 	
   117 	std     s0,8*8(sp)                /* save used callee saved registers     */
   118 	std     a0,9*8(sp)                /* save method pointer for compiler     */
   119 
   120 	std     pv,11*8(sp)               /* save PV register                     */
   121 
   122 	std     itmp3,12*8(sp)            /* registers r14-r31 are callee saved   */
   123 	stfd	ftmp1,13*8(sp)            /* registers f14-f31 are callee saved   */
   124 	stfd	ftmp2,14*8(sp)
   125 
   126 
   127 	SAVE_TEMPORARY_REGISTERS(15)     
   128 	mr	s0, r1			/* save stack pointer */
   129 
   130 	/* a1 contains a pointer to a unit64_t structure filled with all INT_ARG_REG,
   131 	followed by ADR_ARG_CNT and FLT_ARG_CNT, afterwards what else needs to be copied onto
   132 	the stack 
   133 	a2 contains the number of additional stack slots to be copied
   134 	*/
   135 
   136 L_register_copy:
   137 	mr	t1, a1
   138 	mr	t2, a2
   139 
   140 	ld	a0 ,  0*8(t1)
   141 	ld	a1 ,  1*8(t1)
   142 	ld	a2 ,  2*8(t1)
   143 	ld	a3 ,  3*8(t1)
   144 	ld	a4 ,  4*8(t1)
   145 	ld	a5 ,  5*8(t1)
   146 	ld	a6 ,  6*8(t1)
   147 	ld	a7 ,  7*8(t1)
   148 
   149 	lfd	fa0 , 8*8(t1)
   150 	lfd	fa1 , 9*8(t1)
   151 	lfd	fa2 ,10*8(t1)
   152 	lfd	fa3 ,11*8(t1)
   153 	lfd	fa4 ,12*8(t1)
   154 	lfd	fa5 ,13*8(t1)
   155 	lfd	fa6 ,14*8(t1)
   156 	lfd	fa7 ,15*8(t1)
   157 	lfd	fa8 ,16*8(t1)
   158 	lfd	fa9 ,17*8(t1)
   159 	lfd	fa10,18*8(t1)
   160 	lfd	fa11,19*8(t1)
   161 	lfd	fa12,20*8(t1)
   162 
   163 	mr.	t2,t2
   164 	beq L_stack_copy_done
   165 
   166 L_stack_copy:
   167 	addi	t1,t1,20*8		/* before first possible stack slot arg */
   168 	mr	t3,t2			/* argument counter */
   169 	sldi	t2,t2,8			/* calculate size of stack */
   170 	sub	sp,sp,t2		/* increase the stack */
   171 	mr	t2,sp			/* t2 points to bottom of stack now */
   172 
   173 L_stack_copy_loop:
   174 	addi	t1,t1,8			/* next possible stack slot to copy */
   175 	mr.	t3,t3			/* more stack slots to copy ? */
   176 	beq	L_stack_copy_done
   177 	ld	itmp3, 0(t1)
   178 	std	itmp3, 0(t2)
   179 	addi	t2,t2,8
   180 	addi	t3,t3,-1
   181 	b L_stack_copy_loop
   182 
   183 L_stack_copy_done:
   184 	mr	itmp1, s0		/* fake invokevirtual invocation */
   185 	addi	itmp1, itmp1, 9*8	/* address of methods pv */
   186 	ld 	pv,0*8(itmp1)
   187 	mtctr   pv
   188 	bctrl
   189 1:
   190 	mflr    itmp1
   191 	addi    pv,itmp1,(.asm_vm_call_method - 1b)@l
   192 
   193 L_asm_vm_call_method_return:
   194 	mr      sp,s0                     /* restore the function's sp            */
   195 
   196 	ld      s0,8*8(sp)                /* restore used callee saved registers  */
   197 
   198 	ld      pv,11*8(sp)               /* save PV register                     */
   199 
   200 	ld      itmp3,12*8(sp)
   201 	lfd     ftmp1,13*8(sp)            /* registers f14-f31 are callee saved   */
   202 	lfd     ftmp2,14*8(sp)
   203 
   204 	RESTORE_TEMPORARY_REGISTERS(15) 
   205 
   206 	ld     r0,40*8+LA_LR_OFFSET(r1)
   207 	mtlr   r0
   208 	addi   r1,r1,40*8
   209 	blr
   210 
   211 asm_vm_call_method_exception_handler:
   212 	mr      r3,itmp1
   213 	bl      builtin_throw_exception
   214 	b       L_asm_vm_call_method_return
   215 
   216 asm_vm_call_method_end:
   217 	nop
   218 
   219 
   220 /********************* function asm_handle_exception ***************************
   221 *                                                                              *
   222 *   This function handles an exception. It does not use the usual calling      *
   223 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
   224 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
   225 *   the local exception table for a handler. If no one is found, it unwinds    *
   226 *   stacks and continues searching the callers.                                *
   227 *                                                                              *
   228 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
   229 *                                                                              *
   230 *******************************************************************************/
   231 		
   232 asm_handle_nat_exception:
   233 L_asm_handle_nat_exception:             /* required for PIC code              */
   234 L_asm_handle_exception_stack_loop:
   235 	mflr    r0
   236 	addi    sp,sp,-(LA_SIZE+PA_SIZE+((4+6)*8))  /* allocate stack (+4 for darwin)     */
   237 	std     xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp)    /* save exception pointer             */
   238 	std     xpc,LA_SIZE+PA_SIZE+(4+1)*8(sp)     /* save exception pc                  */
   239 	std     r0,LA_SIZE+PA_SIZE+(4+3)*8(sp)      /* save return address                */
   240 	li      itmp3,0
   241 	std     itmp3,LA_SIZE+PA_SIZE+(4+4)*8(sp)   /* save maybe-leaf flag (cleared)     */
   242 
   243 	mr      a0,r0                       /* pass return address                */
   244 	bl      md_asm_codegen_get_pv_from_pc   /* get PV from RA                 */
   245 	std     v0,LA_SIZE+PA_SIZE+(4+2)*8(sp)      /* save data segment pointer          */
   246 
   247 	ld      a0,LA_SIZE+PA_SIZE+(4+0)*8(sp)      /* pass xptr                          */
   248 	ld      a1,LA_SIZE+PA_SIZE+(4+1)*8(sp)      /* pass xpc                           */
   249 	ld      a2,LA_SIZE+PA_SIZE+(4+2)*8(sp)      /* pass PV (v0 == a0)                 */
   250 	addi    a3,sp,LA_SIZE+PA_SIZE+((4+6)*8)     /* pass Java SP                       */
   251 
   252 	b       L_asm_handle_exception_continue
   253 
   254 
   255 asm_handle_exception:
   256 L_asm_handle_exception:                 /* required for PIC code              */
   257 	addi    sp,sp,-(ARG_CNT+TMP_CNT)*8  /* create maybe-leaf stackframe       */
   258 
   259 	SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
   260 	SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
   261 
   262 	addi    sp,sp,-(LA_SIZE+PA_SIZE+(4+6)*8)        /* allocate stack                     */
   263 	std     xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp)        /* save exception pointer             */
   264 	std     pv,LA_SIZE+PA_SIZE+(4+2)*8(sp)          /* save data segment pointer          */
   265 	mflr    r0           		                /* save return address                */
   266 	std     r0,LA_SIZE+PA_SIZE+(4+3)*8(sp)		
   267 	li      t0, 1
   268 	std     t0, LA_SIZE+PA_SIZE+(4+4)*8(sp)         /* maybe-leaf flag */
   269 	
   270 	mr      a0,xptr                     /* pass exception pointer             */
   271 	mr      a1,xpc                      /* pass exception pc                  */
   272 	mr      a2,pv                       /* pass data segment pointer          */
   273 	addi    a3,sp,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+(4+6)*8
   274 
   275 
   276 L_asm_handle_exception_continue:
   277 	bl      exceptions_handle_exception
   278 
   279 	mr.     v0,v0
   280 	beq     L_asm_handle_exception_not_catched
   281 
   282 	mr      xpc,v0                              /* move handlerpc into xpc            */
   283 	ld      xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp)    /* restore exception pointer          */
   284 	ld      pv,LA_SIZE+PA_SIZE+(4+2)*8(sp)      /* restore data segment pointer       */
   285 	ld      r0,LA_SIZE+PA_SIZE+(4+3)*8(sp)      /* restore return address             */
   286 	mtlr    r0
   287 	ld      t0,LA_SIZE+PA_SIZE+(4+4)*8(sp)      /* get maybe-leaf flag                */
   288 	addi    sp,sp,LA_SIZE+PA_SIZE+(4+6)*8       /* free stack frame                   */
   289 
   290 	mr.     t0,t0
   291 	beq     L_asm_handle_exception_no_leaf
   292 
   293 	RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
   294 	RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
   295 
   296 	addi    sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
   297 
   298 L_asm_handle_exception_no_leaf:
   299 	mtctr   xpc                         /* jump to the handler                */
   300 	bctr
   301 
   302 L_asm_handle_exception_not_catched:
   303 	ld      xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp)        /* restore exception pointer          */
   304 	ld      pv,LA_SIZE+PA_SIZE+(4+2)*8(sp)          /* restore data segment pointer       */
   305 	ld      r0,LA_SIZE+PA_SIZE+(4+3)*8(sp)          /* restore return address             */
   306 	mtlr    r0
   307 	ld      t0,LA_SIZE+PA_SIZE+(4+4)*8(sp)          /* get maybe-leaf flag                */
   308 	addi    sp,sp,LA_SIZE+PA_SIZE+(4+6)*8           /* free stack frame                   */
   309 
   310 	mr.     t0,t0
   311 	beq     L_asm_handle_exception_no_leaf_stack
   312 
   313 	addi    sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
   314 	li      t0,0                        /* clear the maybe-leaf flag          */
   315 
   316 L_asm_handle_exception_no_leaf_stack:
   317 	lwz     t1,FrameSize(pv)            /* get frame size                     */
   318 	add     t1,sp,t1                    /* pointer to save area               */
   319 
   320 	lwz     t2,IsLeaf(pv)               /* is leaf procedure                  */
   321 	mr.     t2,t2
   322 	bne     L_asm_handle_exception_no_ra_restore
   323 
   324 	ld      r0,LA_LR_OFFSET(t1)         /* restore ra                         */
   325 	mtlr    r0
   326 
   327 L_asm_handle_exception_no_ra_restore:
   328 	mflr    xpc                         /* the new xpc is ra                  */
   329 	mr      t4,xpc                      /* save RA */
   330 	lwz     t2,IntSave(pv)              /* t1 = saved int register count      */
   331 	bl      ex_int1
   332 ex_int1:
   333 	mflr    t3                          /* t3 = current pc                    */
   334 	addi    t3,t3,(ex_int2-ex_int1)@l
   335 	slwi    t2,t2,2                     /* t2 = register count * 4            */
   336 	subf    t3,t2,t3                    /* t3 = IntSave - t2                  */
   337 	mtctr   t3
   338 	bctr
   339 
   340 	ld      s0,-9*8(t1)
   341 	ld      s1,-8*8(t1)
   342 	ld      s2,-7*8(t1)
   343 	ld      s3,-6*8(t1)
   344 	ld      s4,-5*8(t1)
   345 	ld      s5,-4*8(t1)
   346 	ld      s6,-3*8(t1)
   347 	ld      s7,-2*8(t1)
   348 	ld      s8,-1*8(t1)
   349 
   350 ex_int2:
   351 	subf    t1,t2,t1                    /* t1 = t1 - register count * 4       */
   352 	lwz     t2,FltSave(pv)
   353 	bl      ex_flt1
   354 ex_flt1:
   355 	mflr    t3
   356 	addi    t3,t3,(ex_flt2-ex_flt1)@l
   357 	slwi    t2,t2,2                     /* t2 = register count * 4            */
   358 	subf    t3,t2,t3                    /* t3 = FltSave - t2                  */
   359 	mtctr   t3
   360 	bctr
   361 
   362 	lfd     fs0,-10*8(t1)
   363 	lfd     fs1,-9*8(t1)
   364 	lfd     fs2,-8*8(t1)
   365 	lfd     fs3,-7*8(t1)
   366 	lfd     fs4,-6*8(t1)
   367 	lfd     fs5,-5*8(t1)
   368 	lfd     fs6,-4*8(t1)
   369 	lfd     fs7,-3*8(t1)
   370 	lfd     fs8,-2*8(t1)
   371 	lfd     fs9,-1*8(t1)
   372 
   373 ex_flt2:
   374 	mtlr    t4                                   /* restore RA */
   375 	lwz     t1,FrameSize(pv)                     
   376 	add     sp,sp,t1                             /* unwind stack */
   377 	b       L_asm_handle_exception_stack_loop
   378 
   379 
   380 /* asm_abstractmethoderror *****************************************************
   381 
   382    Creates and throws an AbstractMethodError.
   383 
   384 *******************************************************************************/
   385 
   386 asm_abstractmethoderror:
   387 	mflr	r0
   388 	std     r0,LA_LR_OFFSET(sp)
   389 	stdu    sp,-LA_SIZE_ALIGNED(sp)     /* preserve linkage area              */
   390 	addi    a0,sp,LA_SIZE_ALIGNED       /* pass java sp                       */
   391 	mr      a1,r0                       /* pass exception address             */
   392 	bl      exceptions_asm_new_abstractmethoderror
   393 	ld      r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
   394 	mtlr    r0                          /* restore return address             */
   395 	addi    sp,sp,LA_SIZE_ALIGNED
   396 
   397 	mr      xptr,v0                     /* get exception pointer              */
   398 	mr      xpc,r0                      /* we can't use r0 directly in addi   */
   399 	addi    xpc,xpc,-4                  /* exception address is ra - 4        */
   400 	b       L_asm_handle_nat_exception
   401 
   402 
   403 /* asm_cacheflush **************************************************************
   404 	assumes 128 byte cache line size.
   405 	All registers used may be trashed for fun and profit.
   406 *******************************************************************************/
   407 
   408 	.section ".opd","aw"
   409 	.align 3
   410 asm_cacheflush:
   411 		.quad	.asm_cacheflush,.TOC.@tocbase,0
   412 		.previous
   413 		.size asm_cacheflush, 24
   414 		.type .asm_cacheflush,@function
   415 		.globl .asm_cacheflush 
   416 .asm_cacheflush:
   417 	/* construct the AND mask */
   418 	li	r6,   0xffffffffffff8000
   419 	ori	r6,r6,0x000000000000ff80
   420 
   421 	add     r4,r3,r4
   422 	and.	r3,r3,r6
   423 	addi    r4,r4,127
   424 	and.	r4,r4,r6
   425 	mr      r5,r3
   426 1:
   427 	cmpld   r3,r4
   428 	bge     0f
   429 	dcbst   0,r3
   430 	addi    r3,r3,128
   431 	b       1b
   432 0:
   433 	sync
   434 1:
   435 	cmpld   r5,r4
   436 	bge     0f
   437 	icbi    0,r5
   438 	addi    r5,r5,128
   439 	b       1b
   440 0:
   441 	sync
   442 	isync
   443 	blr
   444 
   445 
   446 /* disable exec-stacks ********************************************************/
   447 
   448 #if defined(__linux__) && defined(__ELF__)
   449 	.section .note.GNU-stack,"",%progbits
   450 #endif
   451 
   452 
   453 /*
   454  * These are local overrides for various environment variables in Emacs.
   455  * Please do not remove this and leave it at the end of the file, where
   456  * Emacs will automagically detect them.
   457  * ---------------------------------------------------------------------
   458  * Local variables:
   459  * mode: asm
   460  * indent-tabs-mode: t
   461  * c-basic-offset: 4
   462  * tab-width: 4
   463  * End:
   464  * vim:noexpandtab:sw=4:ts=4:
   465  */