Stefan Ring
Changes: Christian Thalinger
+ Edwin Steiner
- $Id: asmpart.S 4562 2006-03-06 00:30:36Z twisti $
+ $Id: asmpart.S 4653 2006-03-18 04:14:17Z edwin $
*/
.globl asm_wrapper_patcher
+ .globl asm_replacement_out
+ .globl asm_replacement_in
+
.globl asm_cacheflush
.globl asm_initialize_thread_stack
.globl asm_perform_threadswitch
b L_asm_handle_exception
+/* asm_replacement_out *********************************************************
+
+ This code is jumped to from the replacement-out stubs that are executed
+ when a thread reaches an activated replacement point.
+
+ The purpose of asm_replacement_out is to read out the parts of the
+ execution state that cannot be accessed from C code, store this state,
+ and then call the C function replace_me.
+
+ Stack layout:
+ 8 start of stack inside method to replace
+ 0 rplpoint * info on the replacement point that was reached
+
+ NOTE: itmp3 has been clobbered by the replacement-out stub!
+
+*******************************************************************************/
+
+/* some room to accomodate changes of the stack frame size during replacement */
+ /* XXX we should find a cleaner solution here */
+#define REPLACEMENT_ROOM 512
+
+asm_replacement_out:
+ /* create stack frame */
+ addi sp,sp,-(sizeexecutionstate + REPLACEMENT_ROOM) /* XXX align */
+
+ /* save link register */
+ mflr r16
+
+ /* save registers in execution state */
+ stw r0 ,( 0*8+offes_intregs)(sp)
+ stw r1 ,( 1*8+offes_intregs)(sp)
+ stw r2 ,( 2*8+offes_intregs)(sp)
+ stw r3 ,( 3*8+offes_intregs)(sp)
+ stw r4 ,( 4*8+offes_intregs)(sp)
+ stw r5 ,( 5*8+offes_intregs)(sp)
+ stw r6 ,( 6*8+offes_intregs)(sp)
+ stw r7 ,( 7*8+offes_intregs)(sp)
+ stw r8 ,( 8*8+offes_intregs)(sp)
+ stw r9 ,( 9*8+offes_intregs)(sp)
+ stw r10,(10*8+offes_intregs)(sp)
+ stw r11,(11*8+offes_intregs)(sp)
+ stw r12,(12*8+offes_intregs)(sp)
+ stw r13,(13*8+offes_intregs)(sp)
+ stw r14,(14*8+offes_intregs)(sp)
+ stw r15,(15*8+offes_intregs)(sp)
+ stw r16,(16*8+offes_intregs)(sp) /* link register */
+ stw r17,(17*8+offes_intregs)(sp)
+ stw r18,(18*8+offes_intregs)(sp)
+ stw r19,(19*8+offes_intregs)(sp)
+ stw r20,(20*8+offes_intregs)(sp)
+ stw r21,(21*8+offes_intregs)(sp)
+ stw r22,(22*8+offes_intregs)(sp)
+ stw r23,(23*8+offes_intregs)(sp)
+ stw r24,(24*8+offes_intregs)(sp)
+ stw r25,(25*8+offes_intregs)(sp)
+ stw r26,(26*8+offes_intregs)(sp)
+ stw r27,(27*8+offes_intregs)(sp)
+ stw r28,(28*8+offes_intregs)(sp)
+ stw r29,(29*8+offes_intregs)(sp)
+ stw r30,(30*8+offes_intregs)(sp)
+ stw r31,(31*8+offes_intregs)(sp)
+
+ stfd fr0 ,( 0*8+offes_fltregs)(sp)
+ stfd fr1 ,( 1*8+offes_fltregs)(sp)
+ stfd fr2 ,( 2*8+offes_fltregs)(sp)
+ stfd fr3 ,( 3*8+offes_fltregs)(sp)
+ stfd fr4 ,( 4*8+offes_fltregs)(sp)
+ stfd fr5 ,( 5*8+offes_fltregs)(sp)
+ stfd fr6 ,( 6*8+offes_fltregs)(sp)
+ stfd fr7 ,( 7*8+offes_fltregs)(sp)
+ stfd fr8 ,( 8*8+offes_fltregs)(sp)
+ stfd fr9 ,( 9*8+offes_fltregs)(sp)
+ stfd fr10,(10*8+offes_fltregs)(sp)
+ stfd fr11,(11*8+offes_fltregs)(sp)
+ stfd fr12,(12*8+offes_fltregs)(sp)
+ stfd fr13,(13*8+offes_fltregs)(sp)
+ stfd fr14,(14*8+offes_fltregs)(sp)
+ stfd fr15,(15*8+offes_fltregs)(sp)
+ stfd fr16,(16*8+offes_fltregs)(sp)
+ stfd fr17,(17*8+offes_fltregs)(sp)
+ stfd fr18,(18*8+offes_fltregs)(sp)
+ stfd fr19,(19*8+offes_fltregs)(sp)
+ stfd fr20,(20*8+offes_fltregs)(sp)
+ stfd fr21,(21*8+offes_fltregs)(sp)
+ stfd fr22,(22*8+offes_fltregs)(sp)
+ stfd fr23,(23*8+offes_fltregs)(sp)
+ stfd fr24,(24*8+offes_fltregs)(sp)
+ stfd fr25,(25*8+offes_fltregs)(sp)
+ stfd fr26,(26*8+offes_fltregs)(sp)
+ stfd fr27,(27*8+offes_fltregs)(sp)
+ stfd fr28,(28*8+offes_fltregs)(sp)
+ stfd fr29,(29*8+offes_fltregs)(sp)
+ stfd fr30,(30*8+offes_fltregs)(sp)
+ stfd fr31,(31*8+offes_fltregs)(sp)
+
+ /* calculate sp of method */
+ addi itmp1,sp,(sizeexecutionstate + REPLACEMENT_ROOM + 4*4)
+ stw itmp1,(offes_sp)(sp)
+
+ /* store pv */
+ stw pv,(offes_pv)(sp)
+
+ /* call replace_me */
+ lwz a0,-(4*4)(itmp1) /* arg0: rplpoint * */
+ mr a1,sp /* arg1: execution state */
+ addi sp,sp,-(LA_SIZE_ALIGNED)
+ b replace_me /* call C function replace_me */
+
+/* asm_replacement_in **********************************************************
+
+ This code writes the given execution state and jumps to the replacement
+ code.
+
+ This function never returns!
+
+ NOTE: itmp3 is not restored!
+
+ C prototype:
+ void asm_replacement_in(executionstate *es);
+
+*******************************************************************************/
+
+asm_replacement_in:
+ /* a0 == executionstate *es */
+
+ /* set new sp and pv */
+ lwz sp,(offes_sp)(a0)
+ lwz pv,(offes_pv)(a0)
+
+ /* copy registers from execution state */
+ lwz r0 ,( 0*8+offes_intregs)(a0)
+ /* r1 is sp */
+ /* r2 is reserved */
+ /* a0 is loaded below */
+ lwz r4 ,( 4*8+offes_intregs)(a0)
+ lwz r5 ,( 5*8+offes_intregs)(a0)
+ lwz r6 ,( 6*8+offes_intregs)(a0)
+ lwz r7 ,( 7*8+offes_intregs)(a0)
+ lwz r8 ,( 8*8+offes_intregs)(a0)
+ lwz r9 ,( 9*8+offes_intregs)(a0)
+ lwz r10,(10*8+offes_intregs)(a0)
+ lwz r11,(11*8+offes_intregs)(a0)
+ lwz r12,(12*8+offes_intregs)(a0)
+ /* r13 is pv */
+ lwz r14,(14*8+offes_intregs)(a0)
+ lwz r15,(15*8+offes_intregs)(a0)
+ lwz r16,(16*8+offes_intregs)(a0) /* link register */
+ lwz r17,(17*8+offes_intregs)(a0)
+ lwz r18,(18*8+offes_intregs)(a0)
+ lwz r19,(19*8+offes_intregs)(a0)
+ lwz r20,(20*8+offes_intregs)(a0)
+ lwz r21,(21*8+offes_intregs)(a0)
+ lwz r22,(22*8+offes_intregs)(a0)
+ lwz r23,(23*8+offes_intregs)(a0)
+ lwz r24,(24*8+offes_intregs)(a0)
+ lwz r25,(25*8+offes_intregs)(a0)
+ lwz r26,(26*8+offes_intregs)(a0)
+ lwz r27,(27*8+offes_intregs)(a0)
+ lwz r28,(28*8+offes_intregs)(a0)
+ lwz r29,(29*8+offes_intregs)(a0)
+ lwz r30,(30*8+offes_intregs)(a0)
+ lwz r31,(31*8+offes_intregs)(a0)
+
+ lfd fr0 ,( 0*8+offes_fltregs)(a0)
+ lfd fr1 ,( 1*8+offes_fltregs)(a0)
+ lfd fr2 ,( 2*8+offes_fltregs)(a0)
+ lfd fr3 ,( 3*8+offes_fltregs)(a0)
+ lfd fr4 ,( 4*8+offes_fltregs)(a0)
+ lfd fr5 ,( 5*8+offes_fltregs)(a0)
+ lfd fr6 ,( 6*8+offes_fltregs)(a0)
+ lfd fr7 ,( 7*8+offes_fltregs)(a0)
+ lfd fr8 ,( 8*8+offes_fltregs)(a0)
+ lfd fr9 ,( 9*8+offes_fltregs)(a0)
+ lfd fr10,(10*8+offes_fltregs)(a0)
+ lfd fr11,(11*8+offes_fltregs)(a0)
+ lfd fr12,(12*8+offes_fltregs)(a0)
+ lfd fr13,(13*8+offes_fltregs)(a0)
+ lfd fr14,(14*8+offes_fltregs)(a0)
+ lfd fr15,(15*8+offes_fltregs)(a0)
+ lfd fr16,(16*8+offes_fltregs)(a0)
+ lfd fr17,(17*8+offes_fltregs)(a0)
+ lfd fr18,(18*8+offes_fltregs)(a0)
+ lfd fr19,(19*8+offes_fltregs)(a0)
+ lfd fr20,(20*8+offes_fltregs)(a0)
+ lfd fr21,(21*8+offes_fltregs)(a0)
+ lfd fr22,(22*8+offes_fltregs)(a0)
+ lfd fr23,(23*8+offes_fltregs)(a0)
+ lfd fr24,(24*8+offes_fltregs)(a0)
+ lfd fr25,(25*8+offes_fltregs)(a0)
+ lfd fr26,(26*8+offes_fltregs)(a0)
+ lfd fr27,(27*8+offes_fltregs)(a0)
+ lfd fr28,(28*8+offes_fltregs)(a0)
+ lfd fr29,(29*8+offes_fltregs)(a0)
+ lfd fr30,(30*8+offes_fltregs)(a0)
+ lfd fr31,(31*8+offes_fltregs)(a0)
+
+ /* restore link register */
+
+ mtlr r16
+
+ /* load new pc */
+
+ lwz itmp3,offes_pc(a0)
+
+ /* load a0 */
+
+ lwz a0,(3*8+offes_intregs)(a0)
+
+ /* jump to new code */
+
+ mtctr itmp3
+ bctr
+
+/*********************************************************************/
+
asm_cacheflush:
add r4,r3,r4
rlwinm r3,r3,0,0,26
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/
rp->target = target;
-#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__)) && defined(ENABLE_JIT)
+#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__)) && defined(ENABLE_JIT)
md_patch_replacement_point(rp);
#endif
}
rp->target = NULL;
-#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__)) && defined(ENABLE_JIT)
+#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__)) && defined(ENABLE_JIT)
md_patch_replacement_point(rp);
#endif
}
*******************************************************************************/
+inline static void replace_read_value(executionstate *es,
+#ifdef HAS_4BYTE_STACKSLOT
+ u4 *sp,
+#else
+ u8 *sp,
+#endif
+ rplalloc *ra,
+ u8 *javaval)
+{
+ if (ra->flags & INMEMORY) {
+ /* XXX HAS_4BYTE_STACKSLOT may not be the right discriminant here */
+#ifdef HAS_4BYTE_STACKSLOT
+ if (IS_2_WORD_TYPE(ra->type)) {
+ *javaval = *(u8*)(sp + ra->index);
+ }
+ else {
+#endif
+ *javaval = sp[ra->index];
+#ifdef HAS_4BYTE_STACKSLOT
+ }
+#endif
+ }
+ else {
+ /* allocated register */
+ if (IS_FLT_DBL_TYPE(ra->type)) {
+ *javaval = es->fltregs[ra->index];
+ }
+ else {
+ *javaval = es->intregs[ra->index];
+ }
+ }
+}
+
+inline static void replace_write_value(executionstate *es,
+#ifdef HAS_4BYTE_STACKSLOT
+ u4 *sp,
+#else
+ u8 *sp,
+#endif
+ rplalloc *ra,
+ u8 *javaval)
+{
+ if (ra->flags & INMEMORY) {
+ /* XXX HAS_4BYTE_STACKSLOT may not be the right discriminant here */
+#ifdef HAS_4BYTE_STACKSLOT
+ if (IS_2_WORD_TYPE(ra->type)) {
+ *(u8*)(sp + ra->index) = *javaval;
+ }
+ else {
+#endif
+ sp[ra->index] = *javaval;
+#ifdef HAS_4BYTE_STACKSLOT
+ }
+#endif
+ }
+ else {
+ /* allocated register */
+ if (IS_FLT_DBL_TYPE(ra->type)) {
+ es->fltregs[ra->index] = *javaval;
+ }
+ else {
+ es->intregs[ra->index] = *javaval;
+ }
+ }
+}
+
static void replace_read_executionstate(rplpoint *rp,executionstate *es,
sourcestate *ss)
{
/* in some cases the top stack slot is passed in REG_ITMP1 */
if ( (rp->type == BBTYPE_EXH)
-#if defined(__ALPHA__)
+#if defined(__ALPHA__) || defined(__POWERPC__)
|| (rp->type == BBTYPE_SBR)
#endif
)
ss->javalocals[i] = (u8) 0x00dead0000dead00ULL;
/* some entries in the intregs array are not meaningful */
- es->intregs[REG_ITMP3] = (u8) 0x11dead1111dead11ULL;
+ /*es->intregs[REG_ITMP3] = (u8) 0x11dead1111dead11ULL;*/
es->intregs[REG_SP ] = (u8) 0x11dead1111dead11ULL;
#ifdef REG_PV
es->intregs[REG_PV ] = (u8) 0x11dead1111dead11ULL;
if (t == -1)
continue; /* dummy rplalloc */
-#ifdef HAS_4BYTE_STACKSLOT
- if (IS_2_WORD_TYPE(ra->type)) {
- if (ra->flags & INMEMORY) {
- ss->javalocals[i*5+t] = *(u8*)(sp + ra->index);
- }
- else {
- dolog("XXX split 2-word types in registers are not supported");
- assert(0);
- }
- }
- else {
-#endif
- if (ra->flags & INMEMORY) {
- ss->javalocals[i*5+t] = sp[ra->index];
- }
- else {
- ss->javalocals[i*5+t] = es->intregs[ra->index];
- }
-#ifdef HAS_4BYTE_STACKSLOT
- }
-#endif
+ replace_read_value(es,sp,ra,ss->javalocals + (5*i+t));
}
/* read stack slots */
for (; count--; ra++, i++) {
assert(ra->next);
- if (ra->flags & INMEMORY) {
- ss->javastack[i] = sp[ra->index];
- }
- else {
- ss->javastack[i] = es->intregs[ra->index];
- }
+ replace_read_value(es,sp,ra,ss->javastack + i);
}
/* read unused callee saved int regs */
code = rp->code;
m = code->m;
md = m->parseddesc;
+ topslot = TOP_IS_NORMAL;
/* calculate stack pointer */
/* in some cases the top stack slot is passed in REG_ITMP1 */
if ( (rp->type == BBTYPE_EXH)
-#if defined(__ALPHA__)
+#if defined(__ALPHA__) || defined(__POWERPC__)
|| (rp->type == BBTYPE_SBR)
#endif
)
if (t == -1)
continue; /* dummy rplalloc */
-#ifdef HAS_4BYTE_STACKSLOT
- if (IS_2_WORD_TYPE(ra->type)) {
- if (ra->flags & INMEMORY) {
- *(u8*)(sp + ra->index) = ss->javalocals[i*5+t];
- }
- else {
- dolog("XXX split 2-word types in registers are not supported");
- assert(0);
- }
- }
- else {
-#endif
- if (ra->flags & INMEMORY) {
- sp[ra->index] = ss->javalocals[i*5+t];
- }
- else {
- es->intregs[ra->index] = ss->javalocals[i*5+t];
- }
-#ifdef HAS_4BYTE_STACKSLOT
- }
-#endif
+ replace_write_value(es,sp,ra,ss->javalocals + (5*i+t));
}
/* write stack slots */
for (; count--; ra++, i++) {
assert(ra->next);
- if (ra->flags & INMEMORY) {
- sp[ra->index] = ss->javastack[i];
- }
- else {
- es->intregs[ra->index] = ss->javastack[i];
- }
+ replace_write_value(es,sp,ra,ss->javastack + i);
}
/* write unused callee saved int regs */
/* enter new code */
-#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__)) && defined(ENABLE_JIT)
+#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__)) && defined(ENABLE_JIT)
asm_replacement_in(es);
#endif
abort();