Fri Jul 25 18:51:45 CEST 2003 Paolo Molaro <lupus@ximian.com>
authorPaolo Molaro <lupus@oddwiz.org>
Fri, 25 Jul 2003 17:28:25 +0000 (17:28 -0000)
committerPaolo Molaro <lupus@oddwiz.org>
Fri, 25 Jul 2003 17:28:25 +0000 (17:28 -0000)
* cpu-g4.md, cpu-pentium.md: updates for new instructions.
* mini.c, mini.h: first cut at generics support: some new instructions
added and changed the behaviour of some of the existing ones.

svn path=/trunk/mono/; revision=16678

mono/mini/ChangeLog
mono/mini/cpu-g4.md
mono/mini/cpu-pentium.md
mono/mini/mini.c
mono/mini/mini.h

index c41caa71570724d278ecd105834fa6acf28d2e5f..55b4ab5267b1e93c3ee690aeef385727fbd968ad 100644 (file)
@@ -1,3 +1,10 @@
+
+Fri Jul 25 18:51:45 CEST 2003 Paolo Molaro <lupus@ximian.com>
+
+       * cpu-g4.md, cpu-pentium.md: updates for new instructions.
+       * mini.c, mini.h: first cut at generics support: some new instructions 
+       added and changed the behaviour of some of the existing ones.
+
 2003-07-21  Miguel de Icaza  <miguel@ximian.com>
 
        * mini.c: Removed definition of metadata_shared mutex here.
@@ -702,3 +709,4 @@ Mon Apr 7 16:31:34 CEST 2003 Paolo Molaro <lupus@ximian.com>
        * mini.pc.in: Call this package `mini' for the moment.
 
 
+
index ea863a6ce6743328489411b2a24d217e1495ee0f..629cf6a9c91dafcdebfef9894346a6ce10c3b5b5 100644 (file)
@@ -80,7 +80,6 @@ ldc.i4:
 ldc.i8:
 ldc.r4:
 ldc.r8:
-unused99:
 dup:
 pop:
 jmp:
@@ -163,8 +162,6 @@ newobj:
 castclass:
 isinst:
 conv.r.un:
-unused58:
-unused1:
 unbox:
 throw: src1:i len:8
 ldfld:
@@ -207,19 +204,6 @@ stelem.i8:
 stelem.r4:
 stelem.r8:
 stelem.ref:
-unused5:
-unused6:
-unused7:
-unused8:
-unused9:
-unused10:
-unused11:
-unused12:
-unused13:
-unused14:
-unused15:
-unused16:
-unused17:
 conv.ovf.i1:
 conv.ovf.u1:
 conv.ovf.i2:
@@ -228,27 +212,9 @@ conv.ovf.i4:
 conv.ovf.u4:
 conv.ovf.i8:
 conv.ovf.u8:
-unused50:
-unused18:
-unused19:
-unused20:
-unused21:
-unused22:
-unused23:
 refanyval:
 ckfinite: dest:f src1:f len:22
-unused24:
-unused25:
 mkrefany:
-unused59:
-unused60:
-unused61:
-unused62:
-unused63:
-unused64:
-unused65:
-unused66:
-unused67:
 ldtoken:
 conv.u2: dest:i src1:i len:4
 conv.u1: dest:i src1:i len:4
@@ -267,29 +233,6 @@ leave:
 leave.s:
 stind.i:
 conv.u: dest:i src1:i len:4
-unused26:
-unused27:
-unused28:
-unused29:
-unused30:
-unused31:
-unused32:
-unused33:
-unused34:
-unused35:
-unused36:
-unused37:
-unused38:
-unused39:
-unused40:
-unused41:
-unused42:
-unused43:
-unused44:
-unused45:
-unused46:
-unused47:
-unused48:
 prefix7:
 prefix6:
 prefix5:
@@ -306,7 +249,6 @@ clt: dest:i len:12
 clt.un: dest:i len:12
 ldftn:
 ldvirtftn:
-unused56:
 ldarg:
 ldarga:
 starg:
@@ -314,25 +256,16 @@ ldloc:
 ldloca:
 stloc:
 localloc: dest:i src1:i len:30
-unused57:
 endfilter:
 unaligned.:
 volatile.:
 tail.:
 initobj:
-unused68:
 cpblk:
 initblk:
-unused69:
 rethrow:
-unused:
 sizeof:
 refanytype:
-unused52:
-unused53:
-unused54:
-unused55:
-unused70:
 illegal:
 endmac:
 mono_func1:
index 5c291469d292a7a8721651b3c8ddea0ba8e7d19b..abbb7b1c134336d9d7fa3101cbf9904cd886ef21 100644 (file)
@@ -85,7 +85,6 @@ ldc.i4:
 ldc.i8:
 ldc.r4:
 ldc.r8:
-unused99:
 dup:
 pop:
 jmp: len:32
@@ -168,8 +167,6 @@ newobj:
 castclass:
 isinst:
 conv.r.un:
-unused58:
-unused1:
 unbox:
 throw: src1:i len:6
 ldfld:
@@ -212,19 +209,6 @@ stelem.i8:
 stelem.r4:
 stelem.r8:
 stelem.ref:
-unused5:
-unused6:
-unused7:
-unused8:
-unused9:
-unused10:
-unused11:
-unused12:
-unused13:
-unused14:
-unused15:
-unused16:
-unused17:
 conv.ovf.i1:
 conv.ovf.u1:
 conv.ovf.i2:
@@ -233,27 +217,9 @@ conv.ovf.i4:
 conv.ovf.u4:
 conv.ovf.i8:
 conv.ovf.u8:
-unused50:
-unused18:
-unused19:
-unused20:
-unused21:
-unused22:
-unused23:
 refanyval:
 ckfinite: dest:f src1:f len:22
-unused24:
-unused25:
 mkrefany:
-unused59:
-unused60:
-unused61:
-unused62:
-unused63:
-unused64:
-unused65:
-unused66:
-unused67:
 ldtoken:
 conv.u2: dest:i src1:i len:3
 conv.u1: dest:i src1:i len:3
@@ -272,29 +238,6 @@ leave:
 leave.s:
 stind.i:
 conv.u: dest:i src1:i len:3
-unused26:
-unused27:
-unused28:
-unused29:
-unused30:
-unused31:
-unused32:
-unused33:
-unused34:
-unused35:
-unused36:
-unused37:
-unused38:
-unused39:
-unused40:
-unused41:
-unused42:
-unused43:
-unused44:
-unused45:
-unused46:
-unused47:
-unused48:
 prefix7:
 prefix6:
 prefix5:
@@ -311,7 +254,6 @@ clt: dest:i len:6
 clt.un: dest:i len:6
 ldftn:
 ldvirtftn:
-unused56:
 ldarg:
 ldarga:
 starg:
@@ -319,25 +261,16 @@ ldloc:
 ldloca:
 stloc:
 localloc: dest:i src1:i len:32
-unused57:
 endfilter:
 unaligned.:
 volatile.:
 tail.:
 initobj:
-unused68:
 cpblk:
 initblk:
-unused69:
 rethrow:
-unused:
 sizeof:
 refanytype:
-unused52:
-unused53:
-unused54:
-unused55:
-unused70:
 illegal:
 endmac:
 mono_func1:
index c65402303414bed77b1896f8a5d33bab0ef8718a..2901296b966b632c749b66c8471dcf7e32fcc071 100644 (file)
@@ -778,6 +778,10 @@ handle_enum:
                return CEE_LDOBJ;
        case MONO_TYPE_TYPEDBYREF:
                return CEE_LDOBJ;
+       case MONO_TYPE_GENERICINST:
+               if (type->data.generic_inst->generic_type->type == MONO_TYPE_VALUETYPE)
+                       return CEE_LDOBJ;
+               return CEE_LDIND_REF;
        default:
                g_error ("unknown type 0x%02x in type_to_ldind", type->type);
        }
@@ -831,6 +835,10 @@ handle_enum:
                return CEE_STOBJ;
        case MONO_TYPE_TYPEDBYREF:
                return CEE_STOBJ;
+       case MONO_TYPE_GENERICINST:
+               if (type->data.generic_inst->generic_type->type == MONO_TYPE_VALUETYPE)
+                       return CEE_STOBJ;
+               return CEE_STIND_REF;
        default:
                g_error ("unknown type 0x%02x in type_to_stind", type->type);
        }
@@ -896,6 +904,14 @@ handle_enum:
                inst->klass = mono_defaults.typed_reference_class;
                inst->type = STACK_VTYPE;
                return;
+       case MONO_TYPE_GENERICINST:
+               if (type->data.generic_inst->generic_type->type == MONO_TYPE_VALUETYPE) {
+                       inst->klass = mono_class_from_mono_type (type);
+                       inst->type = STACK_VTYPE;
+               } else {
+                       inst->type = STACK_OBJ;
+               }
+               return;
        default:
                g_error ("unknown type 0x%02x in eval stack type", type->type);
        }
@@ -1285,6 +1301,7 @@ mono_compile_create_var (MonoCompile *cfg, MonoType *type, int opcode)
                cfg->vars = (MonoMethodVar **)g_realloc (cfg->vars, sizeof (MonoMethodVar*) * cfg->varinfo_count);      
        }
 
+       /*g_print ("created temp %d of type 0x%x\n", num, type->type);*/
        mono_jit_stats.allocate_var++;
 
        MONO_INST_NEW (cfg, inst, opcode);
@@ -2331,6 +2348,9 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
 #define CHECK_STACK(num) if ((sp - stack_start) < (num)) goto unverified
 #define CHECK_STACK_OVF(num) if (((sp - stack_start) + (num)) > header->max_stack) goto unverified
 
+#define TYPE_PARAM_TO_TYPE(num) (method->klass->generic_inst->data.generic_inst->type_argv [(num)])
+#define TYPE_PARAM_TO_CLASS(num) (mono_class_from_mono_type (TYPE_PARAM_TO_TYPE ((num))))
+
 /* offset from br.s -> br like opcodes */
 #define BIG_BRANCH_OFFSET 13
 
@@ -2407,6 +2427,19 @@ unverified:
        return 1;
 }
 
+static MonoClassField *
+get_generic_field_inst (MonoClassField *field, MonoClass *klass, MonoClass **retclass)
+{
+       int i;
+       for (i = 0; i < field->parent->field.count; ++i) {
+               if (field == &field->parent->fields [i]) {
+                       *retclass = klass;
+                       return &klass->fields [i];
+               }
+       }
+       return NULL;
+}
+
 /*
  * mono_method_to_ir: translates IL into basic blocks containing trees
  */
@@ -2451,6 +2484,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                bbhash = g_hash_table_new (g_direct_hash, NULL);
        }
 
+       if (cfg->verbose_level > 2)
+               g_print ("method to IR %s\n", mono_method_full_name (method, TRUE));
+
        if (cfg->prof_options & MONO_PROFILE_INS_COVERAGE)
                cfg->coverage_info = mono_profiler_coverage_alloc (cfg->method, header->code_size);
 
@@ -3423,6 +3459,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                klass = mono_class_get (image, token);
 
                        mono_class_init (klass);
+                       if (klass->byval_arg.type == MONO_TYPE_VAR)
+                               klass = TYPE_PARAM_TO_CLASS (klass->byval_arg.data.type_param);
                        n = mono_class_value_size (klass, NULL);
                        ins = mono_compile_create_var (cfg, &klass->byval_arg, OP_LOCAL);
                        NEW_TEMPLOADA (cfg, iargs [0], ins->inst_c0);
@@ -3609,6 +3647,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                klass = mono_class_get (image, token);
                        mono_class_init (klass);
 
+                       if (klass->byval_arg.type == MONO_TYPE_VAR)
+                               klass = TYPE_PARAM_TO_CLASS (klass->byval_arg.data.type_param);
 
                        MONO_INST_NEW (cfg, ins, OP_UNBOXCAST);
                        ins->type = STACK_OBJ;
@@ -3633,6 +3673,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        --sp;
                        klass = mono_class_get (image, read32 (ip + 1));
                        mono_class_init (klass);
+                       if (klass->byval_arg.type == MONO_TYPE_VAR)
+                               klass = TYPE_PARAM_TO_CLASS (klass->byval_arg.data.type_param);
                        ins->type = STACK_OBJ;
                        ins->inst_left = *sp;
                        ins->klass = klass;
@@ -3672,6 +3714,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        //      goto unverified;
                        token = read32 (ip + 1);
                        field = mono_field_from_token (image, token, &klass);
+                       if (field->parent->gen_params)
+                               field = get_generic_field_inst (field, method->klass, &klass);
                        mono_class_init (klass);
 
                        foffset = klass->valuetype? field->offset - sizeof (MonoObject): field->offset;
@@ -3965,6 +4009,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        else
                                klass = mono_class_get (image, token);
                        mono_class_init (klass);
+                       if (klass->byval_arg.type == MONO_TYPE_VAR)
+                               klass = TYPE_PARAM_TO_CLASS (klass->byval_arg.data.type_param);
                        n = mono_type_to_stind (&klass->byval_arg);
                        if (n == CEE_STOBJ) {
                                handle_stobj (cfg, bblock, sp [0], sp [1], ip, klass, FALSE, FALSE);
@@ -3995,6 +4041,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        else
                                klass = mono_class_get (image, token);
                        mono_class_init (klass);
+                       if (klass->byval_arg.type == MONO_TYPE_VAR)
+                               klass = TYPE_PARAM_TO_CLASS (klass->byval_arg.data.type_param);
 
                        /* much like NEWOBJ */
                        if ((cfg->opt & MONO_OPT_SHARED) || mono_compile_aot) {
@@ -4052,6 +4100,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                klass = mono_class_get (image, token);
 
                        mono_class_init (klass);
+                       if (klass->byval_arg.type == MONO_TYPE_VAR)
+                               klass = TYPE_PARAM_TO_CLASS (klass->byval_arg.data.type_param);
                        ins->inst_newa_class = klass;
                        ins->inst_newa_len = *sp;
                        ins->type = STACK_OBJ;
@@ -4073,11 +4123,32 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        sp -= 2;
                        klass = mono_class_get (image, read32 (ip + 1));
                        mono_class_init (klass);
+                       if (klass->byval_arg.type == MONO_TYPE_VAR)
+                               klass = TYPE_PARAM_TO_CLASS (klass->byval_arg.data.type_param);
                        NEW_LDELEMA (cfg, ins, sp, klass);
                        ins->cil_code = ip;
                        *sp++ = ins;
                        ip += 5;
                        break;
+               case CEE_LDELEM: {
+                       MonoInst *load;
+                       CHECK_STACK (2);
+                       sp -= 2;
+                       token = read32 (ip + 1);
+                       klass = mono_class_get (image, token);
+                       mono_class_init (klass);
+                       if (klass->byval_arg.type == MONO_TYPE_VAR)
+                               klass = TYPE_PARAM_TO_CLASS (klass->byval_arg.data.type_param);
+                       NEW_LDELEMA (cfg, load, sp, klass);
+                       load->cil_code = ip;
+                       MONO_INST_NEW (cfg, ins, mono_type_to_ldind (&klass->byval_arg));
+                       ins->cil_code = ip;
+                       ins->inst_left = load;
+                       *sp++ = ins;
+                       type_to_eval_stack_type (&klass->byval_arg, ins);
+                       ip += 5;
+                       break;
+               }
                case CEE_LDELEM_I1:
                case CEE_LDELEM_U1:
                case CEE_LDELEM_I2:
@@ -4133,7 +4204,44 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        ++ip;
                        handle_loaded_temps (cfg, bblock, stack_start, sp);
                        MONO_ADD_INS (bblock, ins);
-                       /* FIXME: add the implicit STELEM_REF castclass */
+                       inline_costs += 1;
+                       cfg->disable_ssa = TRUE;
+                       break;
+               }
+               case CEE_STELEM: {
+                       MonoInst *load;
+                       /*
+                        * translate to:
+                        * stind.x (ldelema (array, index), val)
+                        * ldelema does the bounds check
+                        */
+                       CHECK_STACK (3);
+                       sp -= 3;
+                       token = read32 (ip + 1);
+                       klass = mono_class_get (image, token);
+                       mono_class_init (klass);
+                       if (klass->byval_arg.type == MONO_TYPE_VAR)
+                               klass = TYPE_PARAM_TO_CLASS (klass->byval_arg.data.type_param);
+                       if (MONO_TYPE_IS_REFERENCE (&klass->byval_arg)) {
+                               MonoInst *iargs [3];
+                               handle_loaded_temps (cfg, bblock, stack_start, sp);
+
+                               iargs [2] = sp [2];
+                               iargs [1] = sp [1];
+                               iargs [0] = sp [0];
+                       
+                               mono_emit_jit_icall (cfg, bblock, helper_stelem_ref, iargs, ip);
+                       } else {
+                               NEW_LDELEMA (cfg, load, sp, klass);
+                               load->cil_code = ip;
+                               MONO_INST_NEW (cfg, ins, mono_type_to_stind (&klass->byval_arg));
+                               ins->cil_code = ip;
+                               ins->inst_left = load;
+                               ins->inst_right = sp [2];
+                               handle_loaded_temps (cfg, bblock, stack_start, sp);
+                               MONO_ADD_INS (bblock, ins);
+                       }
+                       ip += 5;
                        inline_costs += 1;
                        cfg->disable_ssa = TRUE;
                        break;
@@ -4746,10 +4854,17 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                        klass = mono_method_get_wrapper_data (method, token);
                                else
                                        klass = mono_class_get (image, token);
+                               if (klass->byval_arg.type == MONO_TYPE_VAR)
+                                       klass = TYPE_PARAM_TO_CLASS (klass->byval_arg.data.type_param);
                                handle_initobj (cfg, bblock, *sp, NULL, klass, stack_start, sp);
                                ip += 6;
                                inline_costs += 1;
                                break;
+                       case CEE_CONSTRAINED_:
+                               /* FIXME: implement */
+                               token = read32 (ip + 2);
+                               ip += 6;
+                               break;
                        case CEE_CPBLK:
                        case CEE_INITBLK: {
                                MonoInst *iargs [3];
@@ -4768,6 +4883,16 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                inline_costs += 1;
                                break;
                        }
+                       case CEE_NO_:
+                               if (ip [2] & 0x1)
+                                       ins_flag |= MONO_INST_NOTYPECHECK;
+                               if (ip [2] & 0x2)
+                                       ins_flag |= MONO_INST_NORANGECHECK;
+                               /* we ignore the no-nullcheck for now since we
+                                * really do it explicitly only when doing callvirt->call
+                                */
+                               ip += 3;
+                               break;
                        case CEE_RETHROW: {
                                MonoInst *load;
                                /* FIXME: check we are in a catch handler */
@@ -4802,6 +4927,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        case CEE_REFANYTYPE:
                                g_error ("opcode 0xfe 0x%02x not handled", ip [1]);
                                break;
+                       case CEE_READONLY_:
+                               ip += 2;
+                               break;
                        default:
                                g_error ("opcode 0xfe 0x%02x not handled", ip [1]);
                        }
@@ -5943,6 +6071,8 @@ mono_compile_create_vars (MonoCompile *cfg)
                cfg->ret->inst_vtype = sig->ret;
                cfg->ret->klass = mono_class_from_mono_type (sig->ret);
        }
+       if (cfg->verbose_level > 2)
+               g_print ("creating vars\n");
 
        if (sig->hasthis)
                mono_compile_create_var (cfg, &cfg->method->klass->this_arg, OP_ARG);
@@ -5952,8 +6082,12 @@ mono_compile_create_vars (MonoCompile *cfg)
 
        cfg->locals_start = cfg->num_varinfo;
 
+       if (cfg->verbose_level > 2)
+               g_print ("creating locals\n");
        for (i = 0; i < header->num_locals; ++i)
                mono_compile_create_var (cfg, header->locals [i], OP_LOCAL);
+       if (cfg->verbose_level > 2)
+               g_print ("locals done\n");
 }
 
 #if 0
@@ -6438,14 +6572,14 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, int p
        cfg->intvars = mono_mempool_alloc0 (cfg->mempool, sizeof (guint16) * STACK_MAX * 
                                            ((MonoMethodNormal *)method)->header->max_stack);
 
+       if (cfg->verbose_level > 2)
+               g_print ("converting method %s\n", mono_method_full_name (method, TRUE));
+
        /*
         * create MonoInst* which represents arguments and local variables
         */
        mono_compile_create_vars (cfg);
 
-       if (cfg->verbose_level > 2)
-               g_print ("converting method %s\n", mono_method_full_name (method, TRUE));
-
        if ((i = mono_method_to_ir (cfg, method, NULL, NULL, cfg->locals_start, NULL, NULL, NULL, 0, FALSE)) < 0) {
                if (cfg->prof_options & MONO_PROFILE_JIT_COMPILATION)
                        mono_profiler_method_end_jit (method, MONO_PROFILE_FAILED);
index 7c2bfddee952bd86073f819908555f4ddb404f3f..d7127def1e3838b81e5592184606a5048c20b67a 100644 (file)
@@ -241,9 +241,11 @@ enum {
        MONO_INST_TAILCALL   = 4,
        MONO_INST_VOLATILE   = 4,
        MONO_INST_BRLABEL    = 4,
+       MONO_INST_NOTYPECHECK    = 4,
        MONO_INST_UNALIGNED  = 8,
        /* the address of the variable has been taken */
-       MONO_INST_INDIRECT   = 16
+       MONO_INST_INDIRECT   = 16,
+       MONO_INST_NORANGECHECK   = 16
 };
 
 #define inst_c0 data.op[0].const_val