#define THUNK_SIZE (3 * 4)
-#ifdef __native_client_codegen__
-const guint kNaClAlignment = kNaClAlignmentARM;
-const guint kNaClAlignmentMask = kNaClAlignmentMaskARM;
-gint8 nacl_align_byte = -1; /* 0xff */
-
-guint8 *
-mono_arch_nacl_pad (guint8 *code, int pad)
-{
- /* Not yet properly implemented. */
- g_assert_not_reached ();
- return code;
-}
-
-guint8 *
-mono_arch_nacl_skip_nops (guint8 *code)
-{
- /* Not yet properly implemented. */
- g_assert_not_reached ();
- return code;
-}
-
-#endif /* __native_client_codegen__ */
-
#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
#if __APPLE__
if (v5_supported) {
ARM_BLX_REG (code, reg);
} else {
-#ifdef USE_JUMP_TABLES
- g_assert_not_reached ();
-#endif
ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC);
if (thumb_supported)
ARM_BX (code, reg);
static guint8*
emit_call_seq (MonoCompile *cfg, guint8 *code)
{
-#ifdef USE_JUMP_TABLES
- code = mono_arm_patchable_bl (code, ARMCOND_AL);
-#else
if (cfg->method->dynamic) {
ARM_LDR_IMM (code, ARMREG_IP, ARMREG_PC, 0);
ARM_B (code, 0);
ARM_BL (code, 0);
}
cfg->thunk_area += THUNK_SIZE;
-#endif
return code;
}
guint8*
mono_arm_patchable_b (guint8 *code, int cond)
{
-#ifdef USE_JUMP_TABLES
- gpointer *jte;
-
- jte = mono_jumptable_add_entry ();
- code = mono_arm_load_jumptable_entry (code, jte, ARMREG_IP);
- ARM_BX_COND (code, cond, ARMREG_IP);
-#else
ARM_B_COND (code, cond, 0);
-#endif
return code;
}
guint8*
mono_arm_patchable_bl (guint8 *code, int cond)
{
-#ifdef USE_JUMP_TABLES
- gpointer *jte;
-
- jte = mono_jumptable_add_entry ();
- code = mono_arm_load_jumptable_entry (code, jte, ARMREG_IP);
- ARM_BLX_REG_COND (code, cond, ARMREG_IP);
-#else
ARM_BL_COND (code, cond, 0);
-#endif
- return code;
-}
-
-#ifdef USE_JUMP_TABLES
-guint8*
-mono_arm_load_jumptable_entry_addr (guint8 *code, gpointer *jte, ARMReg reg)
-{
- ARM_MOVW_REG_IMM (code, reg, GPOINTER_TO_UINT(jte) & 0xffff);
- ARM_MOVT_REG_IMM (code, reg, (GPOINTER_TO_UINT(jte) >> 16) & 0xffff);
return code;
}
-guint8*
-mono_arm_load_jumptable_entry (guint8 *code, gpointer* jte, ARMReg reg)
-{
- code = mono_arm_load_jumptable_entry_addr (code, jte, reg);
- ARM_LDR_IMM (code, reg, reg, 0);
- return code;
-}
-#endif
-
static guint8*
mono_arm_emit_tls_get (MonoCompile *cfg, guint8* code, int dreg, int tls_offset)
{
return;
}
-#ifdef USE_JUMP_TABLES
- {
- gpointer *jte = mono_jumptable_get_entry (code);
- g_assert (jte);
- jte [0] = (gpointer) target;
- }
-#else
/*
* The alternative call sequences looks like this:
*
g_assert_not_reached ();
}
// g_print ("patched with 0x%08x\n", ins);
-#endif
}
void
g_assert (arm_is_imm12 (var->inst_offset));
ARM_LDR_IMM (code, dreg, var->inst_basereg, var->inst_offset);
} else {
-#ifdef USE_JUMP_TABLES
- gpointer *jte = mono_jumptable_add_entry ();
- code = mono_arm_load_jumptable_entry (code, jte, dreg);
- jte [0] = ss_trigger_page;
-#else
ARM_LDR_IMM (code, dreg, ARMREG_PC, 0);
ARM_B (code, 0);
*(int*)code = (int)ss_trigger_page;
code += 4;
-#endif
}
ARM_LDR_IMM (code, dreg, dreg, 0);
}
* FIXME: add aot support.
*/
mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_SWITCH, ins->inst_p0);
-#ifdef USE_JUMP_TABLES
- {
- gpointer *jte = mono_jumptable_add_entries (GPOINTER_TO_INT (ins->klass));
- code = mono_arm_load_jumptable_entry_addr (code, jte, ARMREG_IP);
- ARM_LDR_REG_REG_SHIFT (code, ARMREG_PC, ARMREG_IP, ins->sreg1, ARMSHIFT_LSL, 2);
- }
-#else
-
max_len += 4 * GPOINTER_TO_INT (ins->klass);
if (offset + max_len > (cfg->code_size - 16)) {
cfg->code_size += max_len;
ARM_LDR_REG_REG_SHIFT (code, ARMREG_PC, ARMREG_PC, ins->sreg1, ARMSHIFT_LSL, 2);
ARM_NOP (code);
code += 4 * GPOINTER_TO_INT (ins->klass);
-#endif
break;
case OP_CEQ:
case OP_ICEQ:
code = mono_arm_emit_vfp_scratch_save (cfg, code, vfp_scratch1);
code = mono_arm_emit_vfp_scratch_save (cfg, code, vfp_scratch2);
-#ifdef USE_JUMP_TABLES
- {
- gpointer *jte = mono_jumptable_add_entries (2);
- jte [0] = GUINT_TO_POINTER (0xffffffff);
- jte [1] = GUINT_TO_POINTER (0x7fefffff);
- code = mono_arm_load_jumptable_entry_addr (code, jte, ARMREG_IP);
- ARM_FLDD (code, vfp_scratch1, ARMREG_IP, 0);
- }
-#else
ARM_ABSD (code, vfp_scratch2, ins->sreg1);
ARM_FLDD (code, vfp_scratch1, ARMREG_PC, 0);
ARM_B (code, 1);
code += 4;
*(guint32*)code = 0x7fefffff;
code += 4;
-#endif
ARM_CMPD (code, vfp_scratch2, vfp_scratch1);
ARM_FMSTAT (code);
EMIT_COND_SYSTEM_EXCEPTION_FLAGS (ARMCOND_GT, "OverflowException");
switch (ji->type) {
case MONO_PATCH_INFO_SWITCH: {
-#ifdef USE_JUMP_TABLES
- gpointer *jt = mono_jumptable_get_entry (ip);
-#else
gpointer *jt = (gpointer*)(ip + 8);
-#endif
int i;
/* jt is the inlined jump table, 2 instructions after ip
* In the normal case we store the absolute addresses,
/* Initialize the variable from a GOT slot */
mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_SEQ_POINT_INFO, cfg->method);
-#ifdef USE_JUMP_TABLES
- {
- gpointer *jte = mono_jumptable_add_entry ();
- code = mono_arm_load_jumptable_entry (code, jte, ARMREG_IP);
- ARM_LDR_IMM (code, ARMREG_R0, ARMREG_IP, 0);
- }
- /** XXX: is it correct? */
-#else
ARM_LDR_IMM (code, ARMREG_R0, ARMREG_PC, 0);
ARM_B (code, 0);
*(gpointer*)code = NULL;
code += 4;
-#endif
ARM_LDR_REG_REG (code, ARMREG_R0, ARMREG_PC, ARMREG_R0);
g_assert (ins->opcode == OP_REGOFFSET);
if (cfg->arch.seq_point_ss_method_var) {
MonoInst *ss_method_ins = cfg->arch.seq_point_ss_method_var;
MonoInst *bp_method_ins = cfg->arch.seq_point_bp_method_var;
-#ifdef USE_JUMP_TABLES
- gpointer *jte;
-#endif
g_assert (ss_method_ins->opcode == OP_REGOFFSET);
g_assert (arm_is_imm12 (ss_method_ins->inst_offset));
g_assert (bp_method_ins->opcode == OP_REGOFFSET);
g_assert (arm_is_imm12 (bp_method_ins->inst_offset));
-#ifdef USE_JUMP_TABLES
- jte = mono_jumptable_add_entries (3);
- jte [0] = &single_step_tramp;
- jte [1] = breakpoint_tramp;
- code = mono_arm_load_jumptable_entry_addr (code, jte, ARMREG_LR);
-#else
ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC);
ARM_B (code, 1);
*(gpointer*)code = &single_step_tramp;
code += 4;
*(gpointer*)code = breakpoint_tramp;
code += 4;
-#endif
ARM_LDR_IMM (code, ARMREG_IP, ARMREG_LR, 0);
ARM_STR_IMM (code, ARMREG_IP, ss_method_ins->inst_basereg, ss_method_ins->inst_offset);
exc_class = mono_class_load_from_name (mono_defaults.corlib, "System", patch_info->data.name);
ARM_MOV_REG_REG (code, ARMREG_R1, ARMREG_LR);
-#ifdef USE_JUMP_TABLES
- {
- gpointer *jte = mono_jumptable_add_entries (2);
- patch_info->type = MONO_PATCH_INFO_INTERNAL_METHOD;
- patch_info->data.name = "mono_arch_throw_corlib_exception";
- patch_info->ip.i = code - cfg->native_code;
- code = mono_arm_load_jumptable_entry_addr (code, jte, ARMREG_R0);
- ARM_LDR_IMM (code, ARMREG_IP, ARMREG_R0, 0);
- ARM_LDR_IMM (code, ARMREG_R0, ARMREG_R0, 4);
- ARM_BLX_REG (code, ARMREG_IP);
- jte [1] = GUINT_TO_POINTER (exc_class->type_token);
- }
-#else
ARM_LDR_IMM (code, ARMREG_R0, ARMREG_PC, 0);
patch_info->type = MONO_PATCH_INFO_INTERNAL_METHOD;
patch_info->data.name = "mono_arch_throw_corlib_exception";
cfg->thunk_area += THUNK_SIZE;
*(guint32*)(gpointer)code = exc_class->type_token - MONO_TOKEN_TYPE_DEF;
code += 4;
-#endif
break;
}
default:
#define WMC_SIZE (8 * 4)
#define DISTANCE(A, B) (((gint32)(B)) - ((gint32)(A)))
-#ifdef USE_JUMP_TABLES
-static void
-set_jumptable_element (gpointer *base, guint32 index, gpointer value)
-{
- g_assert (base [index] == NULL);
- base [index] = value;
-}
-static arminstr_t *
-load_element_with_regbase_cond (arminstr_t *code, ARMReg dreg, ARMReg base, guint32 jti, int cond)
-{
- if (arm_is_imm12 (jti * 4)) {
- ARM_LDR_IMM_COND (code, dreg, base, jti * 4, cond);
- } else {
- ARM_MOVW_REG_IMM_COND (code, dreg, (jti * 4) & 0xffff, cond);
- if ((jti * 4) >> 16)
- ARM_MOVT_REG_IMM_COND (code, dreg, ((jti * 4) >> 16) & 0xffff, cond);
- ARM_LDR_REG_REG_SHIFT_COND (code, dreg, base, dreg, ARMSHIFT_LSL, 0, cond);
- }
- return code;
-}
-#else
static arminstr_t *
arm_emit_value_and_patch_ldr (arminstr_t *code, arminstr_t *target, guint32 value)
{
*code = value;
return code + 1;
}
-#endif
#ifdef ENABLE_WRONG_METHOD_CHECK
static void
{
int size, i;
arminstr_t *code, *start;
-#ifdef USE_JUMP_TABLES
- gpointer *jte;
-#else
gboolean large_offsets = FALSE;
guint32 **constant_pool_starts;
arminstr_t *vtable_target = NULL;
int extra_space = 0;
-#endif
#ifdef ENABLE_WRONG_METHOD_CHECK
char * cond;
#endif
GSList *unwind_ops;
size = BASE_SIZE;
-#ifdef USE_JUMP_TABLES
- for (i = 0; i < count; ++i) {
- MonoIMTCheckItem *item = imt_entries [i];
- item->chunk_size += 4 * 16;
- if (!item->is_equals)
- imt_entries [item->check_target_idx]->compare_done = TRUE;
- size += item->chunk_size;
- }
-#else
constant_pool_starts = g_new0 (guint32*, count);
for (i = 0; i < count; ++i) {
if (large_offsets)
size += 4 * count; /* The ARM_ADD_REG_IMM to pop the stack */
-#endif
if (fail_tramp)
code = mono_method_alloc_generic_virtual_thunk (domain, size);
}
#endif
-#ifdef USE_JUMP_TABLES
- ARM_PUSH3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
- mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 3 * sizeof (mgreg_t));
-#define VTABLE_JTI 0
-#define IMT_METHOD_OFFSET 0
-#define TARGET_CODE_OFFSET 1
-#define JUMP_CODE_OFFSET 2
-#define RECORDS_PER_ENTRY 3
-#define IMT_METHOD_JTI(idx) (1 + idx * RECORDS_PER_ENTRY + IMT_METHOD_OFFSET)
-#define TARGET_CODE_JTI(idx) (1 + idx * RECORDS_PER_ENTRY + TARGET_CODE_OFFSET)
-#define JUMP_CODE_JTI(idx) (1 + idx * RECORDS_PER_ENTRY + JUMP_CODE_OFFSET)
-
- jte = mono_jumptable_add_entries (RECORDS_PER_ENTRY * count + 1 /* vtable */);
- code = (arminstr_t *) mono_arm_load_jumptable_entry_addr ((guint8 *) code, jte, ARMREG_R2);
- ARM_LDR_IMM (code, ARMREG_IP, ARMREG_R2, VTABLE_JTI);
- set_jumptable_element (jte, VTABLE_JTI, vtable);
-#else
if (large_offsets) {
ARM_PUSH4 (code, ARMREG_R0, ARMREG_R1, ARMREG_IP, ARMREG_PC);
mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 4 * sizeof (mgreg_t));
ARM_LDR_IMM (code, ARMREG_R0, ARMREG_LR, -4);
vtable_target = code;
ARM_LDR_IMM (code, ARMREG_IP, ARMREG_PC, 0);
-#endif
ARM_MOV_REG_REG (code, ARMREG_R0, ARMREG_V5);
for (i = 0; i < count; ++i) {
MonoIMTCheckItem *item = imt_entries [i];
-#ifdef USE_JUMP_TABLES
- guint32 imt_method_jti = 0, target_code_jti = 0;
-#else
arminstr_t *imt_method = NULL, *vtable_offset_ins = NULL, *target_code_ins = NULL;
-#endif
gint32 vtable_offset;
item->code_target = (guint8*)code;
if (item->check_target_idx || fail_case) {
if (!item->compare_done || fail_case) {
-#ifdef USE_JUMP_TABLES
- imt_method_jti = IMT_METHOD_JTI (i);
- code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, imt_method_jti, ARMCOND_AL);
-#else
imt_method = code;
ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0);
-#endif
ARM_CMP_REG_REG (code, ARMREG_R0, ARMREG_R1);
}
-#ifdef USE_JUMP_TABLES
- code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, JUMP_CODE_JTI (i), ARMCOND_NE);
- ARM_BX_COND (code, ARMCOND_NE, ARMREG_R1);
- item->jmp_code = GUINT_TO_POINTER (JUMP_CODE_JTI (i));
-#else
item->jmp_code = (guint8*)code;
ARM_B_COND (code, ARMCOND_NE, 0);
-#endif
} else {
/*Enable the commented code to assert on wrong method*/
#ifdef ENABLE_WRONG_METHOD_CHECK
-#ifdef USE_JUMP_TABLES
- imt_method_jti = IMT_METHOD_JTI (i);
- code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, imt_method_jti, ARMCOND_AL);
-#else
imt_method = code;
ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0);
-#endif
ARM_CMP_REG_REG (code, ARMREG_R0, ARMREG_R1);
cond = code;
ARM_B_COND (code, ARMCOND_EQ, 0);
if (item->has_target_code) {
/* Load target address */
-#ifdef USE_JUMP_TABLES
- target_code_jti = TARGET_CODE_JTI (i);
- code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, target_code_jti, ARMCOND_AL);
- /* Restore registers */
- ARM_POP3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
- mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
- /* And branch */
- ARM_BX (code, ARMREG_R1);
- set_jumptable_element (jte, target_code_jti, item->value.target_code);
-#else
target_code_ins = code;
ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0);
/* Save it to the fourth slot */
ARM_POP4 (code, ARMREG_R0, ARMREG_R1, ARMREG_IP, ARMREG_PC);
code = arm_emit_value_and_patch_ldr (code, target_code_ins, (gsize)item->value.target_code);
-#endif
} else {
vtable_offset = DISTANCE (vtable, &vtable->vtable[item->value.vtable_slot]);
if (!arm_is_imm12 (vtable_offset)) {
* load them both using LDM.
*/
/* Compute target address */
-#ifdef USE_JUMP_TABLES
- ARM_MOVW_REG_IMM (code, ARMREG_R1, vtable_offset & 0xffff);
- if (vtable_offset >> 16)
- ARM_MOVT_REG_IMM (code, ARMREG_R1, (vtable_offset >> 16) & 0xffff);
- /* IP had vtable base. */
- ARM_LDR_REG_REG (code, ARMREG_IP, ARMREG_IP, ARMREG_R1);
- /* Restore registers and branch */
- ARM_POP3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
- mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
- ARM_BX (code, ARMREG_IP);
-#else
vtable_offset_ins = code;
ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0);
ARM_LDR_REG_REG (code, ARMREG_R1, ARMREG_IP, ARMREG_R1);
ARM_POP4 (code, ARMREG_R0, ARMREG_R1, ARMREG_IP, ARMREG_PC);
code = arm_emit_value_and_patch_ldr (code, vtable_offset_ins, vtable_offset);
-#endif
} else {
-#ifdef USE_JUMP_TABLES
- ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, vtable_offset);
- ARM_POP3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
- mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
- ARM_BX (code, ARMREG_IP);
-#else
ARM_POP2 (code, ARMREG_R0, ARMREG_R1);
if (large_offsets) {
mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 2 * sizeof (mgreg_t));
}
mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
ARM_LDR_IMM (code, ARMREG_PC, ARMREG_IP, vtable_offset);
-#endif
}
}
if (fail_case) {
-#ifdef USE_JUMP_TABLES
- set_jumptable_element (jte, GPOINTER_TO_UINT (item->jmp_code), code);
- target_code_jti = TARGET_CODE_JTI (i);
- /* Load target address */
- code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, target_code_jti, ARMCOND_AL);
- /* Restore registers */
- ARM_POP3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
- mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
- /* And branch */
- ARM_BX (code, ARMREG_R1);
- set_jumptable_element (jte, target_code_jti, fail_tramp);
-#else
arm_patch (item->jmp_code, (guchar*)code);
target_code_ins = code;
ARM_POP4 (code, ARMREG_R0, ARMREG_R1, ARMREG_IP, ARMREG_PC);
code = arm_emit_value_and_patch_ldr (code, target_code_ins, (gsize)fail_tramp);
-#endif
item->jmp_code = NULL;
}
-#ifdef USE_JUMP_TABLES
- if (imt_method_jti)
- set_jumptable_element (jte, imt_method_jti, item->key);
-#else
if (imt_method)
code = arm_emit_value_and_patch_ldr (code, imt_method, (guint32)item->key);
code += extra_space;
extra_space = 0;
}
-#endif
} else {
-#ifdef USE_JUMP_TABLES
- code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, IMT_METHOD_JTI (i), ARMCOND_AL);
- ARM_CMP_REG_REG (code, ARMREG_R0, ARMREG_R1);
- code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, JUMP_CODE_JTI (i), ARMCOND_HS);
- ARM_BX_COND (code, ARMCOND_HS, ARMREG_R1);
- item->jmp_code = GUINT_TO_POINTER (JUMP_CODE_JTI (i));
-#else
ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0);
ARM_CMP_REG_REG (code, ARMREG_R0, ARMREG_R1);
item->jmp_code = (guint8*)code;
ARM_B_COND (code, ARMCOND_HS, 0);
++extra_space;
-#endif
}
}
MonoIMTCheckItem *item = imt_entries [i];
if (item->jmp_code) {
if (item->check_target_idx)
-#ifdef USE_JUMP_TABLES
- set_jumptable_element (jte, GPOINTER_TO_UINT (item->jmp_code), imt_entries [item->check_target_idx]->code_target);
-#else
arm_patch (item->jmp_code, imt_entries [item->check_target_idx]->code_target);
-#endif
}
if (i > 0 && item->is_equals) {
int j;
-#ifdef USE_JUMP_TABLES
- for (j = i - 1; j >= 0 && !imt_entries [j]->is_equals; --j)
- set_jumptable_element (jte, IMT_METHOD_JTI (j), imt_entries [j]->key);
-#else
arminstr_t *space_start = constant_pool_starts [i];
for (j = i - 1; j >= 0 && !imt_entries [j]->is_equals; --j) {
space_start = arm_emit_value_and_patch_ldr (space_start, (arminstr_t*)imt_entries [j]->code_target, (guint32)imt_entries [j]->key);
}
-#endif
}
}
}
#endif
-#ifndef USE_JUMP_TABLES
g_free (constant_pool_starts);
-#endif
mono_arch_flush_icache ((guint8*)start, size);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL);
int dreg = ARMREG_LR;
/* Read from another trigger page */
-#ifdef USE_JUMP_TABLES
- gpointer *jte = mono_jumptable_add_entry ();
- code = mono_arm_load_jumptable_entry (code, jte, dreg);
- jte [0] = bp_trigger_page;
-#else
ARM_LDR_IMM (code, dreg, ARMREG_PC, 0);
ARM_B (code, 0);
*(int*)code = (int)bp_trigger_page;
code += 4;
-#endif
ARM_LDR_IMM (code, dreg, dreg, 0);
mono_arch_flush_icache (code - 16, 16);
#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
-#ifdef USE_JUMP_TABLES
-
-static guint16
-decode_imm16 (guint32 insn)
-{
- return (((insn >> 16) & 0xf) << 12) | (insn & 0xfff);
-}
-
-#define INSN_MASK 0xff00000
-#define MOVW_MASK ((3 << 24) | (0 << 20))
-#define MOVT_MASK ((3 << 24) | (4 << 20))
-
-gpointer*
-mono_arch_jumptable_entry_from_code (guint8 *code)
-{
- guint32 insn1 = ((guint32*)code) [0];
- guint32 insn2 = ((guint32*)code) [1];
-
- if (((insn1 & INSN_MASK) == MOVW_MASK) &&
- ((insn2 & INSN_MASK) == MOVT_MASK) ) {
- guint32 imm_lo = decode_imm16 (insn1);
- guint32 imm_hi = decode_imm16 (insn2);
- return (gpointer*) GUINT_TO_POINTER (imm_lo | (imm_hi << 16));
- } else {
- g_assert_not_reached ();
- return NULL;
- }
-}
-
-#undef INSN_MASK
-#undef MOVW_MASK
-#undef MOVT_MASK
-
-void
-mono_arch_patch_callsite (guint8 *method_start, guint8 *code_ptr, guint8 *addr)
-{
- gpointer *jte;
- /*
- * code_ptr is 4 instructions after MOVW/MOVT used to address
- * jumptable entry.
- */
- jte = mono_jumptable_get_entry (code_ptr - 16);
- g_assert ( jte != NULL);
- *jte = addr;
-}
-#else
void
mono_arch_patch_callsite (guint8 *method_start, guint8 *code_ptr, guint8 *addr)
{
g_assert_not_reached ();
}
-#endif
void
mono_arch_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr)
#define arm_is_imm12(v) ((int)(v) > -4096 && (int)(v) < 4096)
-#ifndef USE_JUMP_TABLES
/*
* Return the instruction to jump from code to target, 0 if not
* reachable with a single instruction
}
return 0;
}
-#endif
static inline guint8*
emit_bx (guint8* code, int reg)
{
char *tramp_name;
guint8 *buf, *code = NULL;
-#ifdef USE_JUMP_TABLES
- gpointer *load_get_lmf_addr = NULL, *load_trampoline = NULL;
-#else
guint8 *load_get_lmf_addr = NULL, *load_trampoline = NULL;
gpointer *constants;
-#endif
int i, cfa_offset, regsave_size, lr_offset;
GSList *unwind_ops = NULL;
MonoJumpInfo *ji = NULL;
int buf_len;
-#ifdef USE_JUMP_TABLES
- g_assert (!aot);
-#endif
-
/* Now we'll create in 'buf' the ARM trampoline code. This
is the trampoline code common to all methods */
code += 4;
ARM_LDR_REG_REG (code, ARMREG_R0, ARMREG_PC, ARMREG_R0);
} else {
-#ifdef USE_JUMP_TABLES
- load_get_lmf_addr = mono_jumptable_add_entry ();
- code = mono_arm_load_jumptable_entry (code, load_get_lmf_addr, ARMREG_R0);
-#else
load_get_lmf_addr = code;
code += 4;
-#endif
}
ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC);
code = emit_bx (code, ARMREG_R0);
code += 4;
ARM_LDR_REG_REG (code, ARMREG_IP, ARMREG_PC, ARMREG_IP);
} else {
-#ifdef USE_JUMP_TABLES
- load_trampoline = mono_jumptable_add_entry ();
- code = mono_arm_load_jumptable_entry (code, load_trampoline, ARMREG_IP);
-#else
load_trampoline = code;
code += 4;
-#endif
}
ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC);
code += 4;
ARM_LDR_REG_REG (code, ARMREG_IP, ARMREG_PC, ARMREG_IP);
} else {
-#ifdef USE_JUMP_TABLES
- gpointer *jte = mono_jumptable_add_entry ();
- code = mono_arm_load_jumptable_entry (code, jte, ARMREG_IP);
- jte [0] = mono_interruption_checkpoint_from_trampoline;
-#else
ARM_LDR_IMM (code, ARMREG_IP, ARMREG_PC, 0);
ARM_B (code, 0);
*(gpointer*)code = mono_interruption_checkpoint_from_trampoline;
code += 4;
-#endif
}
ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC);
code = emit_bx (code, ARMREG_IP);
else
code = emit_bx (code, ARMREG_IP);
-#ifdef USE_JUMP_TABLES
- load_get_lmf_addr [0] = mono_get_lmf_addr;
- load_trampoline [0] = (gpointer)mono_get_trampoline_func (tramp_type);
-#else
constants = (gpointer*)code;
constants [0] = mono_get_lmf_addr;
constants [1] = (gpointer)mono_get_trampoline_func (tramp_type);
}
code += 8;
-#endif
/* Flush instruction cache, since we've generated code */
mono_arch_flush_icache (buf, code - buf);
{
guint8 *code, *buf, *tramp;
gpointer *constants;
-#ifndef USE_JUMP_TABLES
guint32 short_branch = FALSE;
-#endif
guint32 size = SPEC_TRAMP_SIZE;
tramp = mono_get_trampoline_code (tramp_type);
if (domain) {
mono_domain_lock (domain);
-#ifdef USE_JUMP_TABLES
- code = buf = mono_domain_code_reserve_align (domain, size, 4);
-#else
code = buf = mono_domain_code_reserve_align (domain, size, 4);
if ((short_branch = branch_for_target_reachable (code + 4, tramp))) {
size = 12;
mono_domain_code_commit (domain, code, SPEC_TRAMP_SIZE, size);
- }
-#endif
+ }
mono_domain_unlock (domain);
} else {
code = buf = mono_global_codeman_reserve (size);
short_branch = FALSE;
}
-#ifdef USE_JUMP_TABLES
- /* For jumptables case we always generate the same code for trampolines,
- * namely
- * push {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}
- * movw lr, lo(jte)
- * movt lr, hi(jte)
- * ldr r1, [lr + 4]
- * bx r1
- */
- ARM_PUSH (code, 0x5fff);
- constants = mono_jumptable_add_entries (2);
- code = mono_arm_load_jumptable_entry_addr (code, constants, ARMREG_LR);
- ARM_LDR_IMM (code, ARMREG_R1, ARMREG_LR, 4);
- code = emit_bx (code, ARMREG_R1);
- constants [0] = arg1;
- constants [1] = tramp;
-#else
/* we could reduce this to 12 bytes if tramp is within reach:
* ARM_PUSH ()
* ARM_BL ()
constants [1] = tramp;
code += 8;
}
-#endif
/* Flush instruction cache, since we've generated code */
mono_arch_flush_icache (buf, code - buf);
guint8 *code, *start;
MonoDomain *domain = mono_domain_get ();
GSList *unwind_ops;
-#ifdef USE_JUMP_TABLES
- gpointer *jte;
- guint32 size = 20;
-#else
- guint32 size = 16;
-#endif
+ guint32 size = 16;
start = code = mono_domain_code_reserve (domain, size);
unwind_ops = mono_arch_get_cie_program ();
-#ifdef USE_JUMP_TABLES
- jte = mono_jumptable_add_entry ();
- code = mono_arm_load_jumptable_entry (code, jte, ARMREG_IP);
- ARM_ADD_REG_IMM8 (code, ARMREG_R0, ARMREG_R0, sizeof (MonoObject));
- code = emit_bx (code, ARMREG_IP);
- jte [0] = addr;
-#else
ARM_LDR_IMM (code, ARMREG_IP, ARMREG_PC, 4);
ARM_ADD_REG_IMM8 (code, ARMREG_R0, ARMREG_R0, sizeof (MonoObject));
code = emit_bx (code, ARMREG_IP);
*(guint32*)code = (guint32)addr;
code += 4;
-#endif
mono_arch_flush_icache (start, code - start);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, m);
g_assert ((code - start) <= size);
{
guint8 *code, *start;
GSList *unwind_ops;
-#ifdef USE_JUMP_TABLES
- int buf_len = 20;
- gpointer *jte;
-#else
int buf_len = 16;
-#endif
MonoDomain *domain = mono_domain_get ();
start = code = mono_domain_code_reserve (domain, buf_len);
unwind_ops = mono_arch_get_cie_program ();
-#ifdef USE_JUMP_TABLES
- jte = mono_jumptable_add_entries (2);
- code = mono_arm_load_jumptable_entry_addr (code, jte, ARMREG_IP);
- ARM_LDR_IMM (code, MONO_ARCH_RGCTX_REG, ARMREG_IP, 0);
- ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, 4);
- ARM_BX (code, ARMREG_IP);
- jte [0] = mrgctx;
- jte [1] = addr;
-#else
ARM_LDR_IMM (code, MONO_ARCH_RGCTX_REG, ARMREG_PC, 0);
ARM_LDR_IMM (code, ARMREG_PC, ARMREG_PC, 0);
*(guint32*)code = (guint32)mrgctx;
code += 4;
*(guint32*)code = (guint32)addr;
code += 4;
-#endif
g_assert ((code - start) <= buf_len);
gboolean mrgctx;
MonoJumpInfo *ji = NULL;
GSList *unwind_ops = NULL;
-#ifdef USE_JUMP_TABLES
- gpointer *jte;
-#endif
mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
index = MONO_RGCTX_SLOT_INDEX (slot);
tramp = mono_arch_create_specific_trampoline (GUINT_TO_POINTER (slot), MONO_TRAMPOLINE_RGCTX_LAZY_FETCH, mono_get_root_domain (), &code_len);
/* Jump to the actual trampoline */
-#ifdef USE_JUMP_TABLES
- jte = mono_jumptable_add_entry ();
- jte [0] = tramp;
- code = mono_arm_load_jumptable_entry (code, jte, ARMREG_R1);
- code = emit_bx (code, ARMREG_R1);
-#else
ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0); /* temp reg */
code = emit_bx (code, ARMREG_R1);
*(gpointer*)code = tramp;
code += 4;
-#endif
}
mono_arch_flush_icache (buf, code - buf);
/* call */
// FIXME: AOT
-#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);
if (single_step)
else
*(gpointer*)code = debugger_agent_breakpoint_from_context;
code += 4;
-#endif
ARM_BLX_REG (code, ARMREG_IP);
/* we're back; save ctx.eip and ctx.esp into the corresponding regs slots. */