ALPHA_DEBUG("mono_arch_nullify_class_init_trampoline");
+ // pcode[-2] ldq t12,n(gp)
+ // pcode[-1] jsr ra,(t12),0x20003efcb40
+ if ((pcode[-2] & 0xFFFF0000) == 0xa77d0000 &&
+ pcode[-1] == 0x6b5b4000)
+ {
+ // Put "unop" into call inst
+ pcode--;
+ alpha_nop(pcode);
+ alpha_nop(pcode);
+ alpha_nop(pcode);
+
+ mono_arch_flush_icache ((code-4), 3*4);
+ }
+ else
+ g_assert_not_reached ();
}
+/*
+** This method is called after delegate method is compiled.
+** We need to patch call site to call compiled method directly
+** (not via trampoline stub)
+** Determine address to patch using fp reg
+**
+*/
void
mono_arch_patch_delegate_trampoline (guint8 *code, guint8 *tramp,
gssize *regs, guint8 *addr)
{
+ unsigned int *pcode = (unsigned int *)code;
+ int reg;
+ short fp_disp, obj_disp;
+ unsigned long *pobj, obj;
+
ALPHA_DEBUG("mono_arch_patch_delegate_trampoline");
+
+ // The call signature for now is
+ // -4 - ldq v0,24(fp)
+ // -3 - ldq v0,40(v0)
+ // -2 - mov v0,t12
+ // -1 - jsr ra,(t12),0x200041476e4
+ // 0 - ldah gp,0(ra)
+ if (((pcode[-4] & 0xFC000000) == 0xA4000000) &&
+ ((pcode[-3] & 0xFC000000) == 0xA4000000) &&
+ ((pcode[-2] & 0xFC000FE0) == 0x44000400) &&
+ ((pcode[-1] & 0xFFFF0000) == 0x6B5B0000))
+ {
+ fp_disp = (pcode[-4] & 0xFFFF);
+ obj_disp = (pcode[-3] & 0xFFFF);
+
+ pobj = regs[15] + fp_disp;
+ obj = *pobj;
+ reg = 0;
+ }
+ // The non-optimized call signature for now is
+ // -5 - ldq v0,24(fp)
+ // -4 - mov v0,v0
+ // -3 - ldq v0,40(v0)
+ // -2 - mov v0,t12
+ // -1 - jsr ra,(t12),0x200041476e4
+ // 0 - ldah gp,0(ra)
+ else if (((pcode[-5] & 0xFC000000) == 0xA4000000) &&
+ ((pcode[-4] & 0xFC000FE0) == 0x44000400) &&
+ ((pcode[-3] & 0xFC000000) == 0xA4000000) &&
+ ((pcode[-2] & 0xFC000FE0) == 0x44000400) &&
+ ((pcode[-1] & 0xFFFF0000) == 0x6B5B0000))
+ {
+ fp_disp = (pcode[-5] & 0xFFFF);
+ obj_disp = (pcode[-3] & 0xFFFF);
+
+ pobj = regs[15] + fp_disp;
+ obj = *pobj;
+ reg = 0;
+ }
+ // Code with linears optimization
+ // -4 - mov reg,v0
+ // -3 - ldq v0,40(v0)
+ // -2 - mov v0,t12
+ // -1 - jsr ra,(t12)
+ // 0 - ldah gp,0(ra)
+ else if (((pcode[-4] & 0xFC000FE0) == 0x44000400) &&
+ ((pcode[-3] & 0xFC000000) == 0xA4000000) &&
+ ((pcode[-2] & 0xFC000FE0) == 0x44000400) &&
+ ((pcode[-1] & 0xFFFF0000) == 0x6B5B0000))
+ {
+ fp_disp = (pcode[-4] >> AXP_REG2_SHIFT) & AXP_REG_MASK;
+ obj_disp = (pcode[-3] & 0xFFFF);
+
+ obj = regs[fp_disp];
+ //obj = *pobj;
+ reg = 0;
+ }
+ else
+ g_assert_not_reached ();
+
+ *((gpointer*)(obj + obj_disp)) = addr;
}
void
g_assert_not_reached ();
}
+/*
+ * This method is only called when running in the Mono Debugger.
+ */
+gpointer
+mono_debugger_create_notification_function (void)
+{
+ guint8 *code;
+ unsigned int *buf;
+
+ code = mono_global_codeman_reserve (16);
+ buf = (unsigned int *)code;
+
+ *buf = 0;
+
+ alpha_call_pal(buf, 0x80);
+ alpha_ret(buf, alpha_ra, 1);
+ //x86_breakpoint (buf);
+ //x86_ret (buf);
+
+ return code;
+}
+