[arm] Implement support for OP_GENERIC_CLASS_INIT.
authorZoltan Varga <vargaz@gmail.com>
Tue, 26 May 2015 00:28:22 +0000 (00:28 +0000)
committerZoltan Varga <vargaz@gmail.com>
Tue, 26 May 2015 00:29:48 +0000 (00:29 +0000)
mono/mini/cpu-arm.md
mono/mini/mini-arm.c
mono/mini/mini-arm.h
mono/mini/tramp-arm.c

index 4e8edbc8d3e0cd421c415601a46e2fb4f04c7d04..caf10c5552f22b803c64f5bc7df56b7ae61e8a0a 100644 (file)
@@ -15,7 +15,7 @@
 #
 # register may have the following values:
 #      i  integer register
-#      a  r3 register (output from calls)
+#      a  r0 register (first argument/result reg)
 #      b  base register (used in address references)
 #      f  floating point register
 #      g  floating point register returned in r0:r1 for soft-float mode
@@ -398,3 +398,5 @@ atomic_store_i4: dest:b src1:i len:28
 atomic_store_u4: dest:b src1:i len:28
 atomic_store_r4: dest:b src1:f len:80
 atomic_store_r8: dest:b src1:f len:32
+
+generic_class_init: src1:a len:44 clob:c
index 527adfac7a4d8ce144c4f6f2efc5ca9a18f34abf..6652d22e4152bc271b52c25141727cc73be048c5 100644 (file)
@@ -5002,6 +5002,35 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        code = emit_move_return_value (cfg, ins, code);
                        break;
                }
+               case OP_GENERIC_CLASS_INIT: {
+                       static int byte_offset = -1;
+                       static guint8 bitmask;
+                       guint32 imm8;
+                       guint8 *jump;
+
+                       if (byte_offset < 0)
+                               mono_marshal_find_bitfield_offset (MonoVTable, initialized, &byte_offset, &bitmask);
+
+                       g_assert (arm_is_imm8 (byte_offset));
+                       ARM_LDRSB_IMM (code, ARMREG_IP, ins->sreg1, byte_offset);
+                       imm8 = mono_arm_is_rotated_imm8 (bitmask, &rot_amount);
+                       g_assert (imm8 >= 0);
+                       ARM_AND_REG_IMM (code, ARMREG_IP, ARMREG_IP, imm8, rot_amount);
+                       ARM_CMP_REG_IMM (code, ARMREG_IP, 0, 0);
+                       jump = code;
+                       ARM_B_COND (code, ARMCOND_NE, 0);
+
+                       /* Uninitialized case */
+                       g_assert (ins->sreg1 == ARMREG_R0);
+
+                       mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
+                                                                (gpointer)"specific_trampoline_generic_class_init");
+                       code = emit_call_seq (cfg, code);
+
+                       /* Initialized case */
+                       arm_patch (jump, code);
+                       break;
+               }
                case OP_LOCALLOC: {
                        /* round the size to 8 bytes */
                        ARM_ADD_REG_IMM8 (code, ins->dreg, ins->sreg1, 7);
index 47806592b6d2ca0891422fdbee669a64a83a02b7..240f118cfede4e690265a042db8aa49cba3ca0a6 100644 (file)
@@ -294,6 +294,7 @@ typedef struct MonoCompileArch {
 #define MONO_ARCH_HAVE_DUMMY_INIT 1
 #define MONO_ARCH_HAVE_SDB_TRAMPOLINES 1
 #define MONO_ARCH_HAVE_PATCH_CODE_NEW 1
+#define MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT 1
 
 #if defined(__native_client__)
 #undef MONO_ARCH_SOFT_DEBUG_SUPPORTED
index 5122c94f326b2712a00c6d7f95b630d76ee4372f..f472862ecebe7a121e8d3a2b13ae6a999d5f9e64 100644 (file)
@@ -248,11 +248,10 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
                        ARM_LDR_REG_REG (code, ARMREG_V2, ARMREG_V2, ARMREG_LR);
                }
        } else {
-               if (tramp_type != MONO_TRAMPOLINE_GENERIC_CLASS_INIT) {
+               if (tramp_type != MONO_TRAMPOLINE_GENERIC_CLASS_INIT)
                        ARM_LDR_IMM (code, ARMREG_V2, ARMREG_LR, 0);
-               }
                else
-                       ARM_MOV_REG_REG (code, ARMREG_V2, MONO_ARCH_VTABLE_REG);
+                       ARM_LDR_IMM (code, ARMREG_V2, ARMREG_SP, 0);
        }
        ARM_LDR_IMM (code, ARMREG_V3, ARMREG_SP, lr_offset);
 
@@ -439,7 +438,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        if (tramp_type == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH)
                ARM_MOV_REG_REG (code, ARMREG_R0, ARMREG_IP);
        ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, regsave_size);
-       if ((tramp_type == MONO_TRAMPOLINE_CLASS_INIT) || (tramp_type == MONO_TRAMPOLINE_GENERIC_CLASS_INIT) || (tramp_type == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH))
+       if (MONO_TRAMPOLINE_TYPE_MUST_RETURN (tramp_type))
                code = emit_bx (code, ARMREG_LR);
        else
                code = emit_bx (code, ARMREG_IP);
@@ -834,73 +833,9 @@ mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo **info, gboo
 gpointer
 mono_arch_create_generic_class_init_trampoline (MonoTrampInfo **info, gboolean aot)
 {
-       guint8 *tramp;
-       guint8 *code, *buf;
-       static int byte_offset = -1;
-       static guint8 bitmask;
-       guint8 *jump;
-       int tramp_size;
-       guint32 code_len, imm8;
-       gint rot_amount;
-       GSList *unwind_ops = NULL;
-       MonoJumpInfo *ji = NULL;
-
-       tramp_size = 64;
-
-       code = buf = mono_global_codeman_reserve (tramp_size);
-
-       if (byte_offset < 0)
-               mono_marshal_find_bitfield_offset (MonoVTable, initialized, &byte_offset, &bitmask);
-
-       g_assert (arm_is_imm8 (byte_offset));
-       ARM_LDRSB_IMM (code, ARMREG_IP, MONO_ARCH_VTABLE_REG, byte_offset);
-       imm8 = mono_arm_is_rotated_imm8 (bitmask, &rot_amount);
-       g_assert (imm8 >= 0);
-       ARM_AND_REG_IMM (code, ARMREG_IP, ARMREG_IP, imm8, rot_amount);
-       ARM_CMP_REG_IMM (code, ARMREG_IP, 0, 0);
-       jump = code;
-       ARM_B_COND (code, ARMCOND_EQ, 0);
-
-       /* Initialized case */
-       ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_LR);   
-
-       /* Uninitialized case */
-       arm_patch (jump, code);
-
-       if (aot) {
-               ji = mono_patch_info_list_prepend (ji, code - buf, MONO_PATCH_INFO_JIT_ICALL_ADDR, "specific_trampoline_generic_class_init");
-               ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0);
-               ARM_B (code, 0);
-               *(gpointer*)code = NULL;
-               code += 4;
-               ARM_LDR_REG_REG (code, ARMREG_PC, ARMREG_PC, ARMREG_R1);
-       } else {
-#ifdef USE_JUMP_TABLES
-               gpointer *jte = mono_jumptable_add_entry ();
-#endif
-               tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_GENERIC_CLASS_INIT, mono_get_root_domain (), &code_len);
-
-               /* Jump to the actual trampoline */
-#ifdef USE_JUMP_TABLES
-               code = mono_arm_load_jumptable_entry (code, jte, ARMREG_R1);
-               jte [0] = tramp;
-               code = emit_bx (code, ARMREG_R1);
-#else
-               ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0); /* temp reg */
-               code = emit_bx (code, ARMREG_R1);
-               *(gpointer*)code = tramp;
-               code += 4;
-#endif
-       }
-
-       mono_arch_flush_icache (buf, code - buf);
-       mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_HELPER, NULL);
-
-       g_assert (code - buf <= tramp_size);
-
-       *info = mono_tramp_info_create ("generic_class_init_trampoline", buf, code - buf, ji, unwind_ops);
-
-       return buf;
+       /* Not used */
+       g_assert_not_reached ();
+       return NULL;
 }
 
 static gpointer