* roottypes.cs: Rename from tree.cs.
[mono.git] / mono / mini / mini-arm.c
index f016350f7ee63a0c89505ee6bd06ee7a86ea2d87..abd311aaa63889632969b7e8b8aa832665482a17 100644 (file)
@@ -214,6 +214,10 @@ is_regsize_var (MonoType *t) {
        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;
        }
@@ -336,8 +340,8 @@ add_general (guint *gr, guint *stack_size, ArgInfo *ainfo, gboolean simple)
                }
        } 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;
@@ -426,6 +430,14 @@ calculate_sizes (MonoMethodSignature *sig, gboolean is_pinvoke)
                        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;
@@ -511,6 +523,12 @@ calculate_sizes (MonoMethodSignature *sig, gboolean is_pinvoke)
                        /* 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:
@@ -1574,6 +1592,21 @@ arm_patch (guchar *code, const guchar *target)
                /* 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);
@@ -1699,6 +1732,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                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;
@@ -1769,16 +1804,19 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        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:
@@ -1830,9 +1868,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        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;
@@ -2254,7 +2289,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        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:
@@ -2341,12 +2376,13 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        /* 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;
@@ -2363,14 +2399,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                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;
@@ -2455,7 +2483,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        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:
@@ -2521,7 +2549,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                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);
@@ -2530,7 +2558,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                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);
@@ -3101,7 +3129,7 @@ mono_arch_emit_this_vret_args (MonoCompile *cfg, MonoCallInst *inst, int this_re
                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) {
@@ -3111,14 +3139,19 @@ mono_arch_emit_this_vret_args (MonoCompile *cfg, MonoCallInst *inst, int this_re
                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