return o;
}
-gpointer*
-mono_arch_get_vcall_slot_addr (guint8 *code, gpointer *regs)
-{
- gpointer vt;
- int displacement;
- vt = mono_arch_get_vcall_slot (code, regs, &displacement);
- if (!vt)
- return NULL;
- return (gpointer*)((char*)vt + displacement);
-}
-
#define MAX_ARCH_DELEGATE_PARAMS 7
gpointer
}
}
+void
+mono_arch_decompose_long_opts (MonoCompile *cfg, MonoInst *ins)
+{
+ switch (ins->opcode) {
+ case OP_LADD_OVF:
+ /* ADC sets the condition code */
+ MONO_EMIT_NEW_BIALU (cfg, OP_ADDCC, ins->dreg + 1, ins->sreg1 + 1, ins->sreg2 + 1);
+ MONO_EMIT_NEW_BIALU (cfg, OP_ADD_OVF_CARRY, ins->dreg + 2, ins->sreg1 + 2, ins->sreg2 + 2);
+ NULLIFY_INS (ins);
+ break;
+ case OP_LADD_OVF_UN:
+ /* ADC sets the condition code */
+ MONO_EMIT_NEW_BIALU (cfg, OP_ADDCC, ins->dreg + 1, ins->sreg1 + 1, ins->sreg2 + 1);
+ MONO_EMIT_NEW_BIALU (cfg, OP_ADD_OVF_UN_CARRY, ins->dreg + 2, ins->sreg1 + 2, ins->sreg2 + 2);
+ NULLIFY_INS (ins);
+ break;
+ case OP_LSUB_OVF:
+ /* SBB sets the condition code */
+ MONO_EMIT_NEW_BIALU (cfg, OP_SUBCC, ins->dreg + 1, ins->sreg1 + 1, ins->sreg2 + 1);
+ MONO_EMIT_NEW_BIALU (cfg, OP_SUB_OVF_CARRY, ins->dreg + 2, ins->sreg1 + 2, ins->sreg2 + 2);
+ NULLIFY_INS (ins);
+ break;
+ case OP_LSUB_OVF_UN:
+ /* SBB sets the condition code */
+ MONO_EMIT_NEW_BIALU (cfg, OP_SUBCC, ins->dreg + 1, ins->sreg1 + 1, ins->sreg2 + 1);
+ MONO_EMIT_NEW_BIALU (cfg, OP_SUB_OVF_UN_CARRY, ins->dreg + 2, ins->sreg1 + 2, ins->sreg2 + 2);
+ NULLIFY_INS (ins);
+ break;
+ case OP_LNEG:
+ /* This is the old version from inssel-long32.brg */
+ MONO_EMIT_NEW_UNALU (cfg, OP_INOT, ins->dreg + 1, ins->sreg1 + 1);
+ MONO_EMIT_NEW_UNALU (cfg, OP_INOT, ins->dreg + 2, ins->sreg1 + 2);
+ /* ADC sets the condition codes */
+ MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ADC_IMM, ins->dreg + 1, ins->dreg + 1, 1);
+ MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ADC_IMM, ins->dreg + 2, ins->dreg + 2, 0);
+ NULLIFY_INS (ins);
+ break;
+ default:
+ break;
+ }
+}
+
/*
* the branch_b0_table should maintain the order of these
* opcodes.
pdata.found = 0;
mono_domain_lock (domain);
- mono_code_manager_foreach (domain->code_mp, search_thunk_slot, &pdata);
+ mono_domain_code_foreach (domain, search_thunk_slot, &pdata);
if (!pdata.found) {
/* this uses the first available slot */
pdata.found = 2;
- mono_code_manager_foreach (domain->code_mp, search_thunk_slot, &pdata);
+ mono_domain_code_foreach (domain, search_thunk_slot, &pdata);
}
mono_domain_unlock (domain);
ppc_load_reg_indexed (code, ins->dreg, ins->sreg2, ins->inst_basereg);
break;
case OP_LOADI4_MEMINDEX:
- case OP_LOADU4_MEMINDEX:
- ppc_lwzx (code, ins->dreg, ins->sreg2, ins->inst_basereg);
#ifdef __mono_ppc64__
- if (ins->opcode == OP_LOADI4_MEMINDEX)
- ppc_extsb (code, ins->dreg, ins->dreg);
+ ppc_lwax (code, ins->dreg, ins->sreg2, ins->inst_basereg);
+ break;
#endif
+ case OP_LOADU4_MEMINDEX:
+ ppc_lwzx (code, ins->dreg, ins->sreg2, ins->inst_basereg);
break;
case OP_LOADU2_MEMINDEX:
ppc_lhzx (code, ins->dreg, ins->sreg2, ins->inst_basereg);
break;
}
#endif
+ case OP_ATOMIC_CAS_I4:
+ CASE_PPC64 (OP_ATOMIC_CAS_I8) {
+ int location = ins->sreg1;
+ int value = ins->sreg2;
+ int comparand = ins->sreg3;
+ guint8 *start, *not_equal, *lost_reservation;
+
+ start = code;
+ if (ins->opcode == OP_ATOMIC_CAS_I4)
+ ppc_lwarx (code, ppc_r0, 0, location);
+#ifdef __mono_ppc64__
+ else
+ ppc_ldarx (code, ppc_r0, 0, location);
+#endif
+ ppc_cmp (code, 0, ins->opcode == OP_ATOMIC_CAS_I4 ? 0 : 1, ppc_r0, comparand);
+
+ not_equal = code;
+ ppc_bc (code, PPC_BR_FALSE, PPC_BR_EQ, 0);
+ if (ins->opcode == OP_ATOMIC_CAS_I4)
+ ppc_stwcxd (code, value, 0, location);
+#ifdef __mono_ppc64__
+ else
+ ppc_stdcxd (code, value, 0, location);
+#endif
+
+ lost_reservation = code;
+ ppc_bc (code, PPC_BR_FALSE, PPC_BR_EQ, 0);
+ ppc_patch (lost_reservation, start);
+
+ ppc_patch (not_equal, code);
+ ppc_mr (code, ins->dreg, ppc_r0);
+ break;
+ }
default:
g_warning ("unknown opcode %s in %s()\n", mono_inst_name (ins->opcode), __FUNCTION__);
break;
}
case MONO_PATCH_INFO_EXC: {
+ MonoClass *exc_class;
+
unsigned char *ip = patch_info->ip.i + cfg->native_code;
i = exception_id_by_name (patch_info->data.target);
if (exc_throw_pos [i]) {
} else {
exc_throw_pos [i] = code;
}
+
+ exc_class = mono_class_from_name (mono_defaults.corlib, "System", patch_info->data.name);
+ g_assert (exc_class);
+
ppc_patch (ip, code);
/*mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_EXC_NAME, patch_info->data.target);*/
- ppc_load (code, ppc_r3, patch_info->data.target);
- /* we got here from a conditional call, so the calling ip is set in lr already */
+ ppc_load (code, ppc_r3, exc_class->type_token);
+ /* we got here from a conditional call, so the calling ip is set in lr */
+ ppc_mflr (code, ppc_r4);
patch_info->type = MONO_PATCH_INFO_INTERNAL_METHOD;
- patch_info->data.name = "mono_arch_throw_exception_by_name";
+ patch_info->data.name = "mono_arch_throw_corlib_exception";
patch_info->ip.i = code - cfg->native_code;
if (FORCE_INDIR_CALL || cfg->method->dynamic) {
ppc_load_func (code, ppc_r0, 0);
ppc_mtctr (code, ppc_r0);
ppc_bcctr (code, PPC_BR_ALWAYS, 0);
} else {
- ppc_b (code, 0);
+ ppc_bl (code, 0);
}
break;
}
if (item->check_target_idx) {
if (!item->compare_done)
item->chunk_size += CMP_SIZE;
- if (fail_tramp)
+ if (item->has_target_code)
item->chunk_size += BR_SIZE + JUMP_IMM32_SIZE;
else
item->chunk_size += LOADSTORE_SIZE + BR_SIZE + JUMP_IMM_SIZE;
} else {
if (fail_tramp) {
item->chunk_size += CMP_SIZE + BR_SIZE + JUMP_IMM32_SIZE * 2;
+ if (!item->has_target_code)
+ item->chunk_size += LOADSTORE_SIZE;
} else {
item->chunk_size += LOADSTORE_SIZE + JUMP_IMM_SIZE;
#if ENABLE_WRONG_METHOD_CHECK
} else {
/* the initial load of the vtable address */
size += PPC_LOAD_SEQUENCE_LENGTH + LOADSTORE_SIZE;
- code = mono_code_manager_reserve (domain->code_mp, size);
+ code = mono_domain_code_reserve (domain, size);
}
start = code;
if (!fail_tramp) {
}
item->jmp_code = code;
ppc_bc (code, PPC_BR_FALSE, PPC_BR_EQ, 0);
- if (fail_tramp) {
+ if (item->has_target_code) {
ppc_load (code, ppc_r0, item->value.target_code);
} else {
ppc_load_reg (code, ppc_r0, (sizeof (gpointer) * item->value.vtable_slot), ppc_r11);
ppc_compare_log (code, 0, MONO_ARCH_IMT_REG, ppc_r0);
item->jmp_code = code;
ppc_bc (code, PPC_BR_FALSE, PPC_BR_EQ, 0);
- ppc_load (code, ppc_r0, item->value.target_code);
+ if (item->has_target_code) {
+ ppc_load (code, ppc_r0, item->value.target_code);
+ } else {
+ g_assert (vtable);
+ ppc_load (code, ppc_r0, & (vtable->vtable [item->value.vtable_slot]));
+ ppc_load_reg_indexed (code, ppc_r0, 0, ppc_r0);
+ }
ppc_mtctr (code, ppc_r0);
ppc_bcctr (code, PPC_BR_ALWAYS, 0);
ppc_patch (item->jmp_code, code);