-static gpointer
-create_function_wrapper (gpointer function)
-{
- guint8 *start, *code;
-
- start = code = mono_global_codeman_reserve (96);
-
- /*
- * Construct the MonoContext structure on the stack.
- */
-
- ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, sizeof (MonoContext));
-
- /* save ip, lr and pc into their correspodings ctx.regs slots. */
- ARM_STR_IMM (code, ARMREG_IP, ARMREG_SP, MONO_STRUCT_OFFSET (MonoContext, regs) + sizeof (mgreg_t) * ARMREG_IP);
- ARM_STR_IMM (code, ARMREG_LR, ARMREG_SP, MONO_STRUCT_OFFSET (MonoContext, regs) + 4 * ARMREG_LR);
- ARM_STR_IMM (code, ARMREG_LR, ARMREG_SP, MONO_STRUCT_OFFSET (MonoContext, regs) + 4 * ARMREG_PC);
-
- /* save r0..r10 and fp */
- ARM_ADD_REG_IMM8 (code, ARMREG_IP, ARMREG_SP, MONO_STRUCT_OFFSET (MonoContext, regs));
- ARM_STM (code, ARMREG_IP, 0x0fff);
-
- /* now we can update fp. */
- ARM_MOV_REG_REG (code, ARMREG_FP, ARMREG_SP);
-
- /* make ctx.esp hold the actual value of sp at the beginning of this method. */
- ARM_ADD_REG_IMM8 (code, ARMREG_R0, ARMREG_FP, sizeof (MonoContext));
- ARM_STR_IMM (code, ARMREG_R0, ARMREG_IP, 4 * ARMREG_SP);
- ARM_STR_IMM (code, ARMREG_R0, ARMREG_FP, MONO_STRUCT_OFFSET (MonoContext, regs) + 4 * ARMREG_SP);
-
- /* make ctx.eip hold the address of the call. */
- ARM_SUB_REG_IMM8 (code, ARMREG_LR, ARMREG_LR, 4);
- ARM_STR_IMM (code, ARMREG_LR, ARMREG_SP, MONO_STRUCT_OFFSET (MonoContext, pc));
-
- /* r0 now points to the MonoContext */
- ARM_MOV_REG_REG (code, ARMREG_R0, ARMREG_FP);
-
- /* call */
-#ifdef USE_JUMP_TABLES
- {
- gpointer *jte = mono_jumptable_add_entry ();
- code = mono_arm_load_jumptable_entry (code, jte, ARMREG_IP);
- jte [0] = function;
- }
-#else
- ARM_LDR_IMM (code, ARMREG_IP, ARMREG_PC, 0);
- ARM_B (code, 0);
- *(gpointer*)code = function;
- code += 4;
-#endif
- ARM_BLX_REG (code, ARMREG_IP);
-
- /* we're back; save ctx.eip and ctx.esp into the corresponding regs slots. */
- ARM_LDR_IMM (code, ARMREG_R0, ARMREG_FP, MONO_STRUCT_OFFSET (MonoContext, pc));
- ARM_STR_IMM (code, ARMREG_R0, ARMREG_FP, MONO_STRUCT_OFFSET (MonoContext, regs) + 4 * ARMREG_LR);
- ARM_STR_IMM (code, ARMREG_R0, ARMREG_FP, MONO_STRUCT_OFFSET (MonoContext, regs) + 4 * ARMREG_PC);
-
- /* make ip point to the regs array, then restore everything, including pc. */
- ARM_ADD_REG_IMM8 (code, ARMREG_IP, ARMREG_FP, MONO_STRUCT_OFFSET (MonoContext, regs));
- ARM_LDM (code, ARMREG_IP, 0xffff);
-
- mono_arch_flush_icache (start, code - start);
- mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_HELPER, NULL);
-
- return start;
-}
-