+#ifdef MONO_ARCH_VTABLE_REG
+ guint8 *tramp;
+ guint8 *code, *buf;
+ guint8 **rgctx_null_jumps;
+ gint32 displace;
+ int tramp_size,
+ depth,
+ index,
+ iPatch = 0,
+ i;
+ gboolean mrgctx;
+ MonoJumpInfo *ji = NULL;
+ GSList *unwind_ops = NULL;
+
+ mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
+ index = MONO_RGCTX_SLOT_INDEX (slot);
+ if (mrgctx)
+ index += MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT / sizeof (gpointer);
+ for (depth = 0; ; ++depth) {
+ int size = mono_class_rgctx_get_array_size (depth, mrgctx);
+
+ if (index < size - 1)
+ break;
+ index -= size - 1;
+ }
+
+ tramp_size = 48 + 16 * depth;
+ if (mrgctx)
+ tramp_size += 4;
+ else
+ tramp_size += 12;
+
+ code = buf = mono_global_codeman_reserve (tramp_size);
+
+ unwind_ops = mono_arch_get_cie_program ();
+
+ rgctx_null_jumps = g_malloc (sizeof (guint8*) * (depth + 2));
+
+ if (mrgctx) {
+ /* get mrgctx ptr */
+ s390_lgr (code, s390_r1, s390_r2);
+ } else {
+ /* load rgctx ptr from vtable */
+ s390_lg (code, s390_r1, 0, s390_r2, G_STRUCT_OFFSET(MonoVTable, runtime_generic_context));
+ /* is the rgctx ptr null? */
+ s390_ltgr (code, s390_r1, s390_r1);
+ /* if yes, jump to actual trampoline */
+ rgctx_null_jumps [iPatch++] = code;
+ s390_jge (code, 0);
+ }
+
+ for (i = 0; i < depth; ++i) {
+ /* load ptr to next array */
+ if (mrgctx && i == 0)
+ s390_lg (code, s390_r1, 0, s390_r1, MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT);
+ else
+ s390_lg (code, s390_r1, 0, s390_r1, 0);
+ s390_ltgr (code, s390_r1, s390_r1);
+ /* if the ptr is null then jump to actual trampoline */
+ rgctx_null_jumps [iPatch++] = code;
+ s390_jge (code, 0);
+ }
+
+ /* fetch slot */
+ s390_lg (code, s390_r1, 0, s390_r1, (sizeof (gpointer) * (index + 1)));
+ /* is the slot null? */
+ s390_ltgr (code, s390_r1, s390_r1);
+ /* if yes, jump to actual trampoline */
+ rgctx_null_jumps [iPatch++] = code;
+ s390_jge (code, 0);
+ /* otherwise return r1 */
+ s390_lgr (code, s390_r2, s390_r1);
+ s390_br (code, s390_r14);
+
+ for (i = 0; i < iPatch; i++) {
+ displace = ((uintptr_t) code - (uintptr_t) rgctx_null_jumps[i]) / 2;
+ s390_patch_rel ((rgctx_null_jumps [i] + 2), displace);
+ }
+
+ g_free (rgctx_null_jumps);
+
+ /* move the rgctx pointer to the VTABLE register */
+ s390_lgr (code, MONO_ARCH_VTABLE_REG, s390_r2);
+
+ tramp = mono_arch_create_specific_trampoline (GUINT_TO_POINTER (slot),
+ MONO_TRAMPOLINE_RGCTX_LAZY_FETCH, mono_get_root_domain (), NULL);
+
+ /* jump to the actual trampoline */
+ displace = (tramp - code) / 2;
+ s390_jg (code, displace);
+
+ mono_arch_flush_icache (buf, code - buf);
+
+ g_assert (code - buf <= tramp_size);
+
+ if (info) {
+ char *name = mono_get_rgctx_fetch_trampoline_name (slot);
+ *info = mono_tramp_info_create (name, buf, code - buf, ji, unwind_ops);
+ g_free (name);
+ }
+
+ return(buf);
+#else