case MONO_TYPE_SZARRAY:
case MONO_TYPE_ARRAY:
return TRUE;
+ case MONO_TYPE_GENERICINST:
+ if (!mono_type_generic_inst_is_valuetype (t))
+ return TRUE;
+ return FALSE;
case MONO_TYPE_VALUETYPE:
return FALSE;
}
}
} else {
if (*gr > ARMREG_R2) {
- *stack_size += 7;
- *stack_size &= ~7;
+ /**stack_size += 7;
+ *stack_size &= ~7;*/
ainfo->offset = *stack_size;
ainfo->reg = ARMREG_SP; /* in the caller */
ainfo->regtype = RegTypeBase;
add_general (&gr, &stack_size, cinfo->args + n, TRUE);
n++;
break;
+ case MONO_TYPE_GENERICINST:
+ if (!mono_type_generic_inst_is_valuetype (sig->params [i])) {
+ cinfo->args [n].size = sizeof (gpointer);
+ add_general (&gr, &stack_size, cinfo->args + n, TRUE);
+ n++;
+ break;
+ }
+ /* Fall through */
case MONO_TYPE_TYPEDBYREF:
case MONO_TYPE_VALUETYPE: {
gint size;
/* FIXME: cinfo->ret.reg = ???;
cinfo->ret.regtype = RegTypeFP;*/
break;
+ case MONO_TYPE_GENERICINST:
+ if (!mono_type_generic_inst_is_valuetype (sig->ret)) {
+ cinfo->ret.reg = ARMREG_R0;
+ break;
+ }
+ break;
case MONO_TYPE_VALUETYPE:
break;
case MONO_TYPE_TYPEDBYREF:
/* branch and exchange: the address is constructed in a reg */
g_assert_not_reached ();
} else {
+ guint32 ccode [3];
+ guint32 *tmp = ccode;
+ ARM_LDR_IMM (tmp, ARMREG_IP, ARMREG_PC, 0);
+ ARM_MOV_REG_REG (tmp, ARMREG_LR, ARMREG_PC);
+ ARM_MOV_REG_REG (tmp, ARMREG_PC, ARMREG_IP);
+ if (ins == ccode [2]) {
+ tmp = (guint32*)code;
+ tmp [-1] = (guint32)target;
+ return;
+ }
+ if (ins == ccode [0]) {
+ tmp = (guint32*)code;
+ tmp [2] = (guint32)target;
+ return;
+ }
g_assert_not_reached ();
}
// g_print ("patched with 0x%08x\n", ins);
mono_debug_record_line_number (cfg, ins, offset);
switch (ins->opcode) {
+ case OP_MEMORY_BARRIER:
+ break;
case OP_TLS_GET:
g_assert_not_reached ();
break;
ARM_LDR_REG_REG (code, ins->dreg, ins->inst_basereg, ins->sreg2);
break;
case OP_LOADI1_MEMINDEX:
- ARM_LDRSB_REG_REG (code, ins->dreg, ins->inst_basereg, ins->sreg2);
+ /* note: the args are reversed in the macro */
+ ARM_LDRSB_REG_REG (code, ins->inst_basereg, ins->dreg, ins->sreg2);
break;
case OP_LOADU1_MEMINDEX:
ARM_LDRB_REG_REG (code, ins->dreg, ins->inst_basereg, ins->sreg2);
break;
case OP_LOADI2_MEMINDEX:
- ARM_LDRSH_REG_REG (code, ins->dreg, ins->inst_basereg, ins->sreg2);
+ /* note: the args are reversed in the macro */
+ ARM_LDRSH_REG_REG (code, ins->inst_basereg, ins->dreg, ins->sreg2);
break;
case OP_LOADU2_MEMINDEX:
- ARM_LDRH_REG_REG (code, ins->dreg, ins->inst_basereg, ins->sreg2);
+ /* note: the args are reversed in the macro */
+ ARM_LDRH_REG_REG (code, ins->inst_basereg, ins->dreg, ins->sreg2);
break;
case OP_LOAD_MEMBASE:
case OP_LOADI4_MEMBASE:
g_assert (imm8 >= 0);
ARM_CMP_REG_IMM (code, ins->sreg1, imm8, rot_amount);
break;
- case OP_X86_TEST_NULL:
- g_assert_not_reached ();
- break;
case CEE_BREAK:
*(int*)code = 0xe7f001f0;
*(int*)code = 0xef9f0001;
code += 4 * GPOINTER_TO_INT (ins->klass);
break;
case OP_CEQ:
- ARM_MOV_REG_IMM8 (code, ins->dreg, 0);
+ ARM_MOV_REG_IMM8_COND (code, ins->dreg, 0, ARMCOND_NE);
ARM_MOV_REG_IMM8_COND (code, ins->dreg, 1, ARMCOND_EQ);
break;
case OP_CLT:
/* save the temp register */
ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, 8);
ARM_STFD (code, tmpreg, ARMREG_SP, 0);
- ARM_LDFD (code, tmpreg, ARMREG_PC, 4);
+ ARM_LDFD (code, tmpreg, ARMREG_PC, 12);
ARM_FPA_ADFD (code, ins->dreg, ins->dreg, tmpreg);
ARM_LDFD (code, tmpreg, ARMREG_SP, 0);
ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, 8);
/* skip the constant pool */
- ARM_B (code, 4);
+ ARM_B (code, 8);
+ code += 4;
*(int*)code = 0x41f00000;
code += 4;
*(int*)code = 0;
case CEE_CONV_R8:
ARM_FLTD (code, ins->dreg, ins->sreg1);
break;
- case OP_X86_FP_LOAD_I8:
- g_assert_not_reached ();
- /*x86_fild_membase (code, ins->inst_basereg, ins->inst_offset, TRUE);*/
- break;
- case OP_X86_FP_LOAD_I4:
- g_assert_not_reached ();
- /*x86_fild_membase (code, ins->inst_basereg, ins->inst_offset, FALSE);*/
- break;
case OP_FCONV_TO_I1:
code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 1, TRUE);
break;
break;
case OP_FCEQ:
ARM_FCMP (code, ARM_FPA_CMF, ins->sreg1, ins->sreg2);
- ARM_MOV_REG_IMM8 (code, ins->dreg, 0);
+ ARM_MOV_REG_IMM8_COND (code, ins->dreg, 0, ARMCOND_NE);
ARM_MOV_REG_IMM8_COND (code, ins->dreg, 1, ARMCOND_EQ);
break;
case OP_FCLT:
case OP_FBGE_UN:
ARM_FCMP (code, ARM_FPA_CMF, ins->sreg1, ins->sreg2);
EMIT_COND_BRANCH_FLAGS (ins, ARMCOND_VS); /* V set */
- EMIT_COND_BRANCH_FLAGS (ins, ARMCOND_CS);
+ EMIT_COND_BRANCH_FLAGS (ins, ARMCOND_GE);
break;
case OP_FBLE:
ARM_FCMP (code, ARM_FPA_CMF, ins->sreg2, ins->sreg1);
case OP_FBLE_UN:
ARM_FCMP (code, ARM_FPA_CMF, ins->sreg2, ins->sreg1);
EMIT_COND_BRANCH_FLAGS (ins, ARMCOND_VS); /* V set */
- EMIT_COND_BRANCH_FLAGS (ins, ARMCOND_CS); /* swapped */
+ EMIT_COND_BRANCH_FLAGS (ins, ARMCOND_GE); /* swapped */
break;
case CEE_CKFINITE: {
/*ppc_stfd (code, ins->sreg1, -8, ppc_sp);
this->sreg1 = this_reg;
this->dreg = mono_regstate_next_int (cfg->rs);
mono_bblock_add_inst (cfg->cbb, this);
- mono_call_inst_add_outarg_reg (inst, this->dreg, this_dreg, FALSE);
+ mono_call_inst_add_outarg_reg (cfg, inst, this->dreg, this_dreg, FALSE);
}
if (vt_reg != -1) {
vtarg->sreg1 = vt_reg;
vtarg->dreg = mono_regstate_next_int (cfg->rs);
mono_bblock_add_inst (cfg->cbb, vtarg);
- mono_call_inst_add_outarg_reg (inst, vtarg->dreg, ARMREG_R0, FALSE);
+ mono_call_inst_add_outarg_reg (cfg, inst, vtarg->dreg, ARMREG_R0, FALSE);
}
}
MonoInst*
mono_arch_get_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
{
- return NULL;
+ MonoInst *ins = NULL;
+ if (cmethod->klass == mono_defaults.thread_class &&
+ strcmp (cmethod->name, "MemoryBarrier") == 0) {
+ MONO_INST_NEW (cfg, ins, OP_MEMORY_BARRIER);
+ }
+ return ins;
}
gboolean