New tests.
[mono.git] / mono / mini / tramp-s390x.c
index c7e48920c8d7aae20fbcd574a0c2c1336af65b55..b635e7ce6b706970b1cf440d82c73976771d8813 100644 (file)
@@ -74,7 +74,7 @@
 
 /*------------------------------------------------------------------*/
 /*                                                                  */
-/* Name                - mono_arch_get_unbox_trampoline                        */
+/* Name                - mono_arch_get_unbox_trampoline                    */
 /*                                                                  */
 /* Function    - Return a pointer to a trampoline which does the   */
 /*               unboxing before calling the method.               */
@@ -99,9 +99,7 @@ mono_arch_get_unbox_trampoline (MonoGenericSharingContext *gsctx, MonoMethod *me
        if (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret))
                this_pos = s390_r3;
 
-       mono_domain_lock (domain);
-       start = code = mono_code_manager_reserve (domain->code_mp, 28);
-       mono_domain_unlock (domain);
+       start = code = mono_domain_code_reserve (domain, 28);
 
        s390_basr (code, s390_r1, 0);
        s390_j    (code, 6);
@@ -121,9 +119,9 @@ mono_arch_get_unbox_trampoline (MonoGenericSharingContext *gsctx, MonoMethod *me
 
 /*------------------------------------------------------------------*/
 /*                                                                  */
-/* Name                - mono_arch_patch_callsite                              */
+/* Name                - mono_arch_patch_callsite                          */
 /*                                                                  */
-/* Function    - Patch a non-virtual callsite so it calls @addr.       */
+/* Function    - Patch a non-virtual callsite so it calls @addr.   */
 /*                                                                  */
 /*------------------------------------------------------------------*/
 
@@ -159,8 +157,16 @@ mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr)
 
 /*========================= End of Function ========================*/
 
+/*------------------------------------------------------------------*/
+/*                                                                  */
+/* Name                - mono_arch_patch_plt_entry.                        */
+/*                                                                  */
+/* Function    - Patch a PLT entry - unused as yet.                */
+/*                                                                  */
+/*------------------------------------------------------------------*/
+
 void
-mono_arch_patch_plt_entry (guint8 *code, guint8 *addr)
+mono_arch_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr)
 {
        g_assert_not_reached ();
 }
@@ -169,14 +175,14 @@ mono_arch_patch_plt_entry (guint8 *code, guint8 *addr)
 
 /*------------------------------------------------------------------*/
 /*                                                                  */
-/* Name                - mono_arch_nullify_class_init_trampoline               */
+/* Name                - mono_arch_nullify_class_init_trampoline           */
 /*                                                                  */
-/* Function    - Nullify a call which calls a class init trampoline    */
+/* Function    - Nullify a call which calls a class init trampoline*/
 /*                                                                  */
 /*------------------------------------------------------------------*/
 
 void
-mono_arch_nullify_class_init_trampoline (guint8 *code, gssize *regs)
+mono_arch_nullify_class_init_trampoline (guint8 *code, mgreg_t *regs)
 {
        char patch[2] = {0x07, 0x00};
 
@@ -187,8 +193,16 @@ mono_arch_nullify_class_init_trampoline (guint8 *code, gssize *regs)
 
 /*========================= End of Function ========================*/
 
+/*------------------------------------------------------------------*/
+/*                                                                  */
+/* Name                - mono_arch_nullify_plt_entry                       */
+/*                                                                  */
+/* Function    - Nullify a PLT entry call.                         */
+/*                                                                  */
+/*------------------------------------------------------------------*/
+
 void
-mono_arch_nullify_plt_entry (guint8 *code)
+mono_arch_nullify_plt_entry (guint8 *code, mgreg_t *regs)
 {
        g_assert_not_reached ();
 }
@@ -197,9 +211,9 @@ mono_arch_nullify_plt_entry (guint8 *code)
 
 /*------------------------------------------------------------------*/
 /*                                                                  */
-/* Name                - mono_arch_get_vcall_slot                              */
+/* Name                - mono_arch_get_vcall_slot                          */
 /*                                                                  */
-/* Function    - This method is called by the arch independent         */
+/* Function    - This method is called by the arch independent     */
 /*            trampoline code to determine the vtable slot used by  */
 /*            the call which invoked the trampoline.                */
 /*                                                                  */
@@ -211,15 +225,19 @@ mono_arch_nullify_plt_entry (guint8 *code)
 /*------------------------------------------------------------------*/
 
 gpointer
-mono_arch_get_vcall_slot (guint8 *code, gpointer *regs, int *displacement)
+mono_arch_get_vcall_slot (guint8 *code, mgreg_t *regs, int *displacement)
 {
        int reg, lkReg;
        guchar* base;
        unsigned short opcode;
        char *sp;
+       MonoLMF *lmf = (MonoLMF *) ((gchar *) regs - sizeof(MonoLMF));
 
        // We are passed sp instead of the register array
-       sp = (char*)regs;
+#if 0
+       sp = (char *) regs;
+#endif
+       sp = (char *) lmf->gregs[s390_r15];
 
        *displacement = 0;
 
@@ -229,7 +247,7 @@ mono_arch_get_vcall_slot (guint8 *code, gpointer *regs, int *displacement)
                return NULL;
 
        /*-----------------------------------*/
-       /* This is a bras r14,Rz instruction */
+       /* This is a basr r14,Rz instruction */
        /* If it's preceded by a LG Rx,d(Ry) */
        /* If Rz == 1 then this is virtual   */
        /* call.                             */
@@ -240,8 +258,7 @@ mono_arch_get_vcall_slot (guint8 *code, gpointer *regs, int *displacement)
        /* If call is preceded by LGR then   */
        /* there's nothing to patch          */
        /*-----------------------------------*/
-       if ((code[0] == 0xb9) &&
-               (code[1] == 0x04))
+       if ((code[0] == 0xb9) && (code[1] == 0x04))
                return NULL;
 
        /*-----------------------------------*/
@@ -259,10 +276,15 @@ mono_arch_get_vcall_slot (guint8 *code, gpointer *regs, int *displacement)
        /* hh  = high 8 bits of displacement */
        /*-----------------------------------*/
        reg      = code[0] >> 4;
-       *displacement = (code[2] << 12) +
-               ((code[0] & 0x0f) << 8) +
-               code[1];
+       *displacement = (code[2] << 12) |
+                       ((code[0] & 0x0f) << 8) |
+                       code[1];
+
+       if (code[2] & 0x80)
+               *displacement |= 0xfff00000;
 
+       base = ((guchar *) lmf->gregs[reg]);
+#if 0
        if (reg > 5)
                base = *((guchar **) (sp + S390_REG_SAVE_OFFSET +
                                                          sizeof(long)*(reg-6)));
@@ -270,6 +292,7 @@ mono_arch_get_vcall_slot (guint8 *code, gpointer *regs, int *displacement)
                base = *((guchar **) ((sp - CREATE_STACK_SIZE) +
                                                          CREATE_GR_OFFSET +
                                                          sizeof(long)*(reg-2)));
+#endif
        if (lkReg != 1)
                /* Non virtual call */
                return NULL;
@@ -279,22 +302,9 @@ mono_arch_get_vcall_slot (guint8 *code, gpointer *regs, int *displacement)
 
 /*========================= End of Function ========================*/
 
-gpointer*
-mono_arch_get_vcall_slot_addr (guint8* code, gpointer *regs)
-{
-       gpointer vt;
-       int displacement;
-       vt = mono_arch_get_vcall_slot (code, regs, &displacement);
-       if (!vt)
-               return NULL;
-       return (gpointer*)((char*)vt + displacement);
-}
-
-/*========================= End of Function ========================*/
-
 /*------------------------------------------------------------------*/
 /*                                                                  */
-/* Name                - mono_arch_create_trampoline_code                            */
+/* Name                - mono_arch_create_trampoline_code                  */
 /*                                                                  */
 /* Function    - Create the designated type of trampoline according*/
 /*                to the 'tramp_type' parameter.                    */
@@ -318,7 +328,7 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
          stack size big enough to save our registers.
          -----------------------------------------------------------*/
                
-       s390_stmg (buf, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
+       s390_stmg (buf, s390_r6, s390_r15, STK_BASE, S390_REG_SAVE_OFFSET);
        s390_lgr  (buf, s390_r11, s390_r15);
        s390_aghi (buf, STK_BASE, -CREATE_STACK_SIZE);
        s390_stg  (buf, s390_r11, 0, STK_BASE, 0);
@@ -403,12 +413,14 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
        /*---------------------------------------------------------------*/     
        /* Save general and floating point registers                     */     
        /*---------------------------------------------------------------*/     
-       s390_stmg  (buf, s390_r2, s390_r12, s390_r13,
-                           G_STRUCT_OFFSET(MonoLMF, gregs[2]));                
-       for (i = 0; i < 16; i++) {
-               s390_std  (buf, i, 0, s390_r13,
-                                  G_STRUCT_OFFSET(MonoLMF, fregs[i]));
-       }                                               
+       s390_mvc   (buf, 4*sizeof(gulong), s390_r13, G_STRUCT_OFFSET(MonoLMF, gregs[2]), 
+                   STK_BASE, CREATE_GR_OFFSET);
+       s390_mvc   (buf, 10*sizeof(gulong), s390_r13, G_STRUCT_OFFSET(MonoLMF, gregs[6]), 
+                   s390_r11, S390_REG_SAVE_OFFSET);
+
+       /* Simply copy fpregs already saved above                        */
+       s390_mvc   (buf, 16*sizeof(double), s390_r13, G_STRUCT_OFFSET(MonoLMF, fregs[0]),
+                   STK_BASE, CREATE_FP_OFFSET);
 
        /*---------------------------------------------------------------*/
        /* STEP 2: call the C trampoline function                        */
@@ -416,9 +428,8 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
                                
        /* Set arguments */
 
-       /* Arg 1: gssize *regs. We pass sp instead */
-       s390_lgr  (buf, s390_r2, STK_BASE);
-       s390_ahi  (buf, s390_r2, CREATE_STACK_SIZE);
+       /* Arg 1: mgreg_t *regs. We pass sp instead */
+       s390_la  (buf, s390_r2, 0, STK_BASE, CREATE_STACK_SIZE);
                
        /* Arg 2: code (next address to the instruction that called us) */
        if (tramp_type == MONO_TRAMPOLINE_JUMP) {
@@ -489,9 +500,9 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
 
 /*------------------------------------------------------------------*/
 /*                                                                  */
-/* Name                - mono_arch_create_specific_trampoline                  */
+/* Name                - mono_arch_create_specific_trampoline              */
 /*                                                                  */
-/* Function    - Creates the given kind of specific trampoline         */
+/* Function    - Creates the given kind of specific trampoline     */
 /*                                                                  */
 /*------------------------------------------------------------------*/
 
@@ -508,9 +519,7 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty
        /* purpose is to provide the generic part with the          */
        /* MonoMethod *method pointer. We'll use r1 to keep it.     */
        /*----------------------------------------------------------*/
-       mono_domain_lock (domain);
-       code = buf = mono_code_manager_reserve (domain->code_mp, SPECIFIC_TRAMPOLINE_SIZE);
-       mono_domain_unlock (domain);
+       code = buf = mono_domain_code_reserve (domain, SPECIFIC_TRAMPOLINE_SIZE);
 
        s390_basr (buf, s390_r1, 0);
        s390_j    (buf, 6);
@@ -533,18 +542,20 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty
 
 /*========================= End of Function ========================*/
 
+/*------------------------------------------------------------------*/
+/*                                                                  */
+/* Name                - mono_arch_create_rgctx_lazy_fetch_trampoline      */
+/*                                                                  */
+/* Function    -                                                   */
+/*                                                                  */
+/*------------------------------------------------------------------*/
+
 gpointer
 mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 encoded_offset)
 {
        /* FIXME: implement! */
        g_assert_not_reached ();
        return NULL;
-}
+}      
 
-guint32
-mono_arch_get_rgctx_lazy_fetch_offset (gpointer *regs)
-{
-       /* FIXME: implement! */
-       g_assert_not_reached ();
-       return 0;
-}
+/*========================= End of Function ========================*/