* src/vm/jit/sparc64/codegen.c: Implemented threads support.
authorajordan <none@none>
Sun, 6 May 2007 13:32:49 +0000 (13:32 +0000)
committerajordan <none@none>
Sun, 6 May 2007 13:32:49 +0000 (13:32 +0000)
* src/vm/jit/sparc64/machine-instr.h: Likewise.
* src/vm/jit/sparc64/linux/md-os.c: Likewise.

src/vm/jit/sparc64/codegen.c
src/vm/jit/sparc64/linux/md-os.c
src/vm/jit/sparc64/machine-instr.h

index 28fe4a9b4aa276c12dd863306cc8a1c74e137b8e..f1a4a14b36b2e870ea24595994991ced877d0e73 100644 (file)
@@ -109,7 +109,7 @@ bool codegen_emit(jitdata *jd)
        codeinfo           *code;
        codegendata        *cd;
        registerdata       *rd;
-       s4                  len, s1, s2, s3, d, disp;
+       s4                  len, s1, s2, s3, d, disp, slots;
        varinfo            *var;
        basicblock         *bptr;
        instruction        *iptr;
@@ -219,7 +219,55 @@ bool codegen_emit(jitdata *jd)
 #endif
        
        
-       
+               /* call monitorenter function */
+#if defined(ENABLE_THREADS)
+       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+               /* stack offset for monitor argument */
+
+               s1 = rd->memuse;
+
+               /* save float argument registers */
+
+               /* XXX jit-c-call */
+               slots = FLT_ARG_CNT;
+               ALIGN_STACK_SLOTS(slots);
+
+               M_LDA(REG_SP, REG_SP, -(slots * 8));
+               for (i = 0; i < FLT_ARG_CNT; i++)
+                       M_DST(abi_registers_float_argument[i], REG_SP, CSTACK +  i * 8);
+
+               s1 += slots;
+
+               /* get correct lock object */
+
+               if (m->flags & ACC_STATIC) {
+                       disp = dseg_add_address(cd, &m->class->object.header);
+                       M_ALD(REG_OUT0, REG_PV, disp);
+                       disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
+                       M_ALD(REG_ITMP3, REG_PV, disp);
+               }
+               else {
+                       /* copy class pointer: $i0 -> $o0 */
+                       M_MOV(REG_RESULT_CALLEE, REG_OUT0);
+                       M_BNEZ(REG_OUT0, 3);
+                       disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
+                       M_ALD(REG_ITMP3, REG_PV, disp);                   /* branch delay */
+                       M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
+               }
+
+               M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
+               M_AST(REG_OUT0, REG_SP, CSTACK + s1 * 8);             /* branch delay */
+
+               /* restore float argument registers */
+
+               for (i = 0; i < FLT_ARG_CNT; i++)
+                       M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
+
+               M_LDA(REG_SP, REG_SP, slots * 8);
+       }
+#endif
+
+
        /* take arguments out of register or stack frame */
        
        md = m->parseddesc;
@@ -310,9 +358,6 @@ bool codegen_emit(jitdata *jd)
                /* release scratch space */
                M_ADD_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
        }
-       
-       
-       /* XXX monitor enter */
 
 
 
@@ -2207,24 +2252,32 @@ nowperformreturn:
 
 #if defined(ENABLE_THREADS)
                        if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
-/* XXX: REG_RESULT is save, but what about FRESULT? */
-                               M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */
+                               /* XXX jit-c-call */
+                               disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
+                               M_ALD(REG_ITMP3, REG_PV, disp);
+
+                               /* we need to save fp return value (int saved by window) */
 
                                switch (iptr->opc) {
                                case ICMD_FRETURN:
                                case ICMD_DRETURN:
-                                       M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
-                                       break;
-                               }
+                                       M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8);
+                                       M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
+                                       M_DST(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8); /* delay */
 
-                               disp = dseg_add_functionptr(cd, BUILTIN_monitorexit);
-                               M_ALD(REG_ITMP3, REG_PV, disp);
-                               M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */
+                                       /* restore the fp return value */
 
-                               switch (iptr->opc) {
-                               case ICMD_FRETURN:
-                               case ICMD_DRETURN:
-                                       M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
+                                       M_DLD(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8);
+                                       break;
+                               case ICMD_IRETURN:
+                               case ICMD_LRETURN:
+                               case ICMD_ARETURN:
+                               case ICMD_RETURN:
+                                       M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
+                                       M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8); /* delay */
+                                       break;
+                               default:
+                                       assert(false);
                                        break;
                                }
                        }
index 5f50a10b2df345512a31c81eea9d6732833ba824..7cb275a512c48f5d4f2983245c0075a45ec63ced 100644 (file)
@@ -152,21 +152,6 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *info , void *_p)
 }
 
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-void thread_restartcriticalsection(ucontext_t *_uc)
-{
-       mcontext_t *_mc;
-       void       *critical;
-
-       _mc = &_uc->uc_mcontext;
-
-       critical = thread_checkcritical((void *) _mc->sc_pc);
-
-       if (critical)
-               _mc->sc_pc = (ptrint) critical;
-}
-#endif
-
 
 /* md_icacheflush **************************************************************
 
@@ -193,9 +178,32 @@ void md_icacheflush(u1 *addr, s4 nbytes)
        }
 }
 
+#if defined(ENABLE_THREADS)
+/* thread_restartcriticalsection **********************************************
+   Reads PC and modifies NPC
 
+******************************************************************************/
 
+void thread_restartcriticalsection(ucontext_t *_uc)
+{
+       mcontext_t *_mc;
+       u1         *pc;
+       u1         *npc;
+
+       _mc = &_uc->uc_mcontext;
+
+       pc = (u1 *) _mc->mc_gregs[MC_PC];
 
+       npc = critical_find_restart_point(pc);
+       assert(npc);
+
+       _mc->mc_gregs[MC_NPC] = (ptrint) npc;
+
+       assert(false);
+}
+#endif
+       
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
index c989a2a5724768140c2cb74f5716f5587ae96f15..b69caa2cdf1e372beccef0803157f755c90ef3fc 100644 (file)
@@ -1,5 +1,8 @@
 #ifndef _MACHINE_INSTR_H
 #define _MACHINE_INSTR_H
+
+#include "toolbox/logging.h"
+
 /*
 static inline void
 __attribute__ ((unused))
@@ -23,6 +26,7 @@ __attribute__ ((unused))
 compare_and_swap (volatile long *p, long oldval, long newval)
 {
   long ret;
+  /*dolog("compare_and_swap(%p [%d], %d, %d)", p, *p, oldval, newval);*/
 
   __asm__ __volatile__ (
     "mov %3,%0\n\t"
@@ -30,6 +34,7 @@ compare_and_swap (volatile long *p, long oldval, long newval)
     : "=&r"(ret), "=m"(*p) 
     : "r"(oldval), "r"(newval), "m"(*p));
 
+  /*dolog("compare_and_swap() return=%d mem=%d", ret, *p);*/
   return ret;
 }
 
@@ -37,6 +42,6 @@ compare_and_swap (volatile long *p, long oldval, long newval)
 #define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("mb" : : : "memory");
 #define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("mb" : : : "memory");
 #define MEMORY_BARRIER() __asm__ __volatile__ ( \
-               "mb" : : : "memory" );
+               "membar 0x0F" : : : "memory" );
 
 #endif