@@ -470,10 +470,54 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
470470 return start ;
471471}
472472
473+ /**
474+ *
475+ * @brief Architecture-specific delegation virtual trampoline processing
476+ *
477+ * @param[in] @sig - Method signature
478+ * @param[in] @method - Method
479+ * @param[in] @offset - Offset into vtable
480+ * @param[in] @load_imt_reg - Whether to load the LMT register
481+ * @returns Trampoline
482+ *
483+ * Return a pointer to a delegation virtual trampoline
484+ */
485+
473486gpointer
474487mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature * sig , MonoMethod * method , int offset , gboolean load_imt_reg )
475488{
476- return NULL ;
489+ guint8 * code , * start ;
490+ int size = 32 ;
491+
492+ start = code = (guint8 * ) mono_global_codeman_reserve (size );
493+
494+ /*
495+ * Replace the "this" argument with the target
496+ */
497+ ppc_mr (code , ppc_r12 , ppc_r3 );
498+ ppc_ldptr (code , ppc_r3 , MONO_STRUCT_OFFSET (MonoDelegate , target ), ppc_r12 );
499+
500+ /*
501+ * Load the IMT register, if needed
502+ */
503+ if (load_imt_reg ) {
504+ ppc_ldptr (code , MONO_ARCH_IMT_REG , MONO_STRUCT_OFFSET (MonoDelegate , method ), ppc_r12 );
505+ }
506+
507+ /*
508+ * Load the vTable
509+ */
510+ ppc_ldptr (code , ppc_r12 , MONO_STRUCT_OFFSET (MonoObject , vtable ), ppc_r3 );
511+ if (!ppc_is_imm16 (offset ))
512+ ppc_addis (code , ppc_r12 , ppc_r12 , ppc_ha (offset ));
513+ ppc_ldptr (code , ppc_r12 , offset , ppc_r12 );
514+ ppc_mtctr (code , ppc_r12 );
515+ ppc_bcctr (code , PPC_BR_ALWAYS , 0 );
516+
517+ mono_arch_flush_icache (start , code - start );
518+ MONO_PROFILER_RAISE (jit_code_buffer , (start , code - start , MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE , NULL ));
519+
520+ return (start );
477521}
478522
479523gpointer
0 commit comments