Blame SOURCES/runtime-77308-ppc64le-delegate.patch

ccd8ec
diff --git a/src/runtime/src/mono/mono/mini/mini-ppc.c b/src/runtime/src/mono/mono/mini/mini-ppc.c
ccd8ec
index db669f8b5da0f..73a26c02b18aa 100644
ccd8ec
--- a/src/runtime/src/mono/mono/mini/mini-ppc.c
ccd8ec
+++ b/src/runtime/src/mono/mono/mini/mini-ppc.c
ccd8ec
@@ -470,10 +470,54 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
ccd8ec
 	return start;
ccd8ec
 }
ccd8ec
 
ccd8ec
+/**
ccd8ec
+ *
ccd8ec
+ * @brief Architecture-specific delegation virtual trampoline processing
ccd8ec
+ *
ccd8ec
+ * @param[in] @sig - Method signature
ccd8ec
+ * @param[in] @method - Method
ccd8ec
+ * @param[in] @offset - Offset into vtable
ccd8ec
+ * @param[in] @load_imt_reg - Whether to load the LMT register
ccd8ec
+ * @returns Trampoline
ccd8ec
+ *
ccd8ec
+ * Return a pointer to a delegation virtual trampoline
ccd8ec
+ */
ccd8ec
+
ccd8ec
 gpointer
ccd8ec
 mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, int offset, gboolean load_imt_reg)
ccd8ec
 {
ccd8ec
-	return NULL;
ccd8ec
+	guint8 *code, *start;
ccd8ec
+	int size = 32;
ccd8ec
+
ccd8ec
+	start = code = (guint8 *) mono_global_codeman_reserve (size);
ccd8ec
+
ccd8ec
+	/*
ccd8ec
+	 * Replace the "this" argument with the target
ccd8ec
+	 */
ccd8ec
+	ppc_mr  (code, ppc_r12, ppc_r3);
ccd8ec
+	ppc_ldptr (code, ppc_r3, MONO_STRUCT_OFFSET(MonoDelegate, target), ppc_r12);
ccd8ec
+
ccd8ec
+	/*
ccd8ec
+	 * Load the IMT register, if needed
ccd8ec
+	 */
ccd8ec
+	if (load_imt_reg) {
ccd8ec
+		ppc_ldptr  (code, MONO_ARCH_IMT_REG, MONO_STRUCT_OFFSET(MonoDelegate, method), ppc_r12);
ccd8ec
+	}
ccd8ec
+
ccd8ec
+	/*
ccd8ec
+	 * Load the vTable
ccd8ec
+	 */
ccd8ec
+	ppc_ldptr  (code, ppc_r12, MONO_STRUCT_OFFSET(MonoObject, vtable), ppc_r3);
ccd8ec
+	if (!ppc_is_imm16(offset))
ccd8ec
+		ppc_addis (code, ppc_r12, ppc_r12, ppc_ha(offset));
ccd8ec
+	ppc_ldptr  (code, ppc_r12, offset, ppc_r12);
ccd8ec
+	ppc_mtctr (code, ppc_r12);
ccd8ec
+	ppc_bcctr (code, PPC_BR_ALWAYS, 0);
ccd8ec
+
ccd8ec
+	mono_arch_flush_icache (start, code - start);
ccd8ec
+	MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL));
ccd8ec
+
ccd8ec
+	return(start);
ccd8ec
 }
ccd8ec
 
ccd8ec
 gpointer