-gpointer
-mono_arch_get_vcall_slot (guint8 *code_ptr, mgreg_t *regs, int *displacement)
-{
- char *o = NULL;
- int reg, offset = 0;
- guint32* code = (guint32*)code_ptr;
- mgreg_t *r = (mgreg_t*)regs;
-
- *displacement = 0;
-
- /* This is the 'blrl' instruction */
- --code;
-
- /* Sanity check: instruction must be 'blrl' */
- if (*code != 0x4e800021)
- return NULL;
-
- if (mono_ppc_is_direct_call_sequence (code))
- return NULL;
-
- /* FIXME: more sanity checks here */
- /* OK, we're now at the 'blrl' instruction. Now walk backwards
- till we get to a 'mtlr rA' */
- for (; --code;) {
- if((*code & 0x7c0803a6) == 0x7c0803a6) {
- gint16 soff;
- /* Here we are: we reached the 'mtlr rA'.
- Extract the register from the instruction */
- reg = (*code & 0x03e00000) >> 21;
- --code;
- /* ok, this is a lwz reg, offset (vtreg)
- * it is emitted with:
- * ppc_emit32 (c, (32 << 26) | ((D) << 21) | ((a) << 16) | (guint16)(d))
- */
- soff = (*code & 0xffff);
- offset = soff;
- reg = (*code >> 16) & 0x1f;
- g_assert (reg != ppc_r1);
- /*g_print ("patching reg is %d\n", reg);*/
- o = (gpointer)(gsize)r [reg];
- break;
- }
- }
- *displacement = offset;
- return o;
-}
-