2007-06-05 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / mini-s390.c
index 4be62c7376f09f8bb3ed52bbd1b30e64d44204d5..4728a071e798121a6f9b1df4676561d91c66c88a 100644 (file)
@@ -267,8 +267,6 @@ int mono_exc_esp_offset = 0;
 
 static int indent_level = 0;
 
-static const char*const * ins_spec = s390_cpu_desc;
-
 static gboolean tls_offset_inited = FALSE;
 
 static int appdomain_tls_offset = -1,
@@ -652,7 +650,6 @@ static void
 enter_method (MonoMethod *method, RegParm *rParm, char *sp)
 {
        int i, oParm = 0, iParm = 0;
-       MonoClass *class;
        MonoObject *obj;
        MonoMethodSignature *sig;
        char *fname;
@@ -662,12 +659,6 @@ enter_method (MonoMethod *method, RegParm *rParm, char *sp)
        size_data sz;
        void *curParm;
 
-
-lc++;
-if (lc > 5000000) {
-fseek(stdout, 0L, SEEK_SET);
-lc = 0;
-}
        fname = mono_method_full_name (method, TRUE);
        indent (1);
        printf ("ENTER: %s(", fname);
@@ -1041,6 +1032,8 @@ is_regsize_var (MonoType *t) {
        case MONO_TYPE_U4:
        case MONO_TYPE_I:
        case MONO_TYPE_U:
+       case MONO_TYPE_PTR:
+       case MONO_TYPE_FNPTR:
                return TRUE;
        case MONO_TYPE_OBJECT:
        case MONO_TYPE_STRING:
@@ -1331,8 +1324,8 @@ enum_retvalue:
                        /* Fall through */
                case MONO_TYPE_VALUETYPE: {
                        MonoClass *klass = mono_class_from_mono_type (sig->ret);
-                       if (sig->ret->data.klass->enumtype) {
-                               simpletype = sig->ret->data.klass->enum_basetype->type;
+                       if (klass->enumtype) {
+                               simpletype = klass->enum_basetype->type;
                                goto enum_retvalue;
                        }
                        if (sig->pinvoke)
@@ -1358,7 +1351,7 @@ enum_retvalue:
                case MONO_TYPE_VOID:
                        break;
                default:
-                       g_error ("Can't handle as return value 0x%x", sig->ret->type);
+                       g_error ("mini-s390: cannot handle as return value 0x%x (0x%x)", sig->ret->type,simpletype);
        }
 
        if (sig->hasthis) {
@@ -1672,7 +1665,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        }
 
        if (sig->hasthis) {
-               inst = cfg->varinfo [0];
+               inst = cfg->args [0];
                if (inst->opcode != OP_REGVAR) {
                        inst->opcode       = OP_REGOFFSET;
                        inst->inst_basereg = frame_reg;
@@ -1691,7 +1684,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                cfg->sig_cookie += S390_MINIMAL_STACK_SIZE;
 
        for (iParm = sArg; iParm < eArg; ++iParm) {
-               inst = cfg->varinfo [curinst];
+               inst = cfg->args [curinst];
                if (inst->opcode != OP_REGVAR) {
                        switch (cinfo->args[iParm].regtype) {
                                case RegTypeStructByAddr :
@@ -1816,7 +1809,7 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
        MonoMethodSignature *sig;
        int i, n, lParamArea;
        CallInfo *cinfo;
-       ArgInfo *ainfo;
+       ArgInfo *ainfo = NULL;
        size_data sz;
        int stackSize;
 
@@ -2280,15 +2273,8 @@ peephole_pass (MonoCompile *cfg, MonoBasicBlock *bb)
                        if (last_ins && (last_ins->opcode == OP_STOREI1_MEMBASE_REG) &&
                                        ins->inst_basereg == last_ins->inst_destbasereg &&
                                        ins->inst_offset == last_ins->inst_offset) {
-                               if (ins->dreg == last_ins->sreg1) {
-                                       last_ins->next = ins->next;                             
-                                       ins = ins->next;                                
-                                       continue;
-                               } else {
-                                       //static int c = 0; printf ("MATCHX %s %d\n", cfg->method->name,c++);
-                                       ins->opcode = OP_MOVE;
-                                       ins->sreg1 = last_ins->sreg1;
-                               }
+                               ins->opcode = (ins->opcode == OP_LOADI1_MEMBASE) ? CEE_CONV_I1 : CEE_CONV_U1;
+                               ins->sreg1 = last_ins->sreg1;                           
                        }
                        break;
                case OP_LOADU2_MEMBASE:
@@ -2296,14 +2282,8 @@ peephole_pass (MonoCompile *cfg, MonoBasicBlock *bb)
                        if (last_ins && (last_ins->opcode == OP_STOREI2_MEMBASE_REG) &&
                                        ins->inst_basereg == last_ins->inst_destbasereg &&
                                        ins->inst_offset == last_ins->inst_offset) {
-                               if (ins->dreg == last_ins->sreg1) {
-                                       last_ins->next = ins->next;                             
-                                       ins = ins->next;                                
-                                       continue;
-                               } else {
-                                       ins->opcode = OP_MOVE;
-                                       ins->sreg1 = last_ins->sreg1;
-                               }
+                               ins->opcode = (ins->opcode == OP_LOADI2_MEMBASE) ? CEE_CONV_I2 : CEE_CONV_U2;
+                               ins->sreg1 = last_ins->sreg1;                           
                        }
                        break;
                case CEE_CONV_I4:
@@ -2463,7 +2443,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
        while (ins) {
                offset = code - cfg->native_code;
 
-               max_len = ((guint8 *)ins_spec [ins->opcode])[MONO_INST_LEN];
+               max_len = ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN];
 
                if (offset > (cfg->code_size - max_len - 16)) {
                        cfg->code_size *= 2;
@@ -2739,7 +2719,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        }
                }
                        break;
-               case CEE_BREAK: {
+               case OP_BREAK: {
                        mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_ABS, mono_arch_break);
                         s390_brasl (code, s390_r14, 0);
                }
@@ -2839,7 +2819,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;
                case OP_LADD: {
-                       short int *o[1];
                        s390_alr  (code, s390_r0, ins->sreg1);
                        s390_jnc  (code, 4);
                        s390_ahi  (code, s390_r1, 1);
@@ -3368,7 +3347,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                s390_ledbr (code, ins->dreg, ins->sreg1);
                }
                        break;
-               case CEE_JMP: {
+               case OP_JMP: {
                        if (cfg->method->save_lmf)
                                restoreLMF(code, cfg->frame_reg, cfg->stack_usage);
 
@@ -3520,7 +3499,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_br  (code, s390_r14);
                }
                        break;
-               case CEE_THROW: {
+               case OP_THROW: {
                        s390_lr (code, s390_r2, ins->sreg1);
                        mono_add_patch_info (cfg, code-cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, 
                                             (gpointer)"mono_arch_throw_exception");
@@ -3566,7 +3545,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_br  (code, s390_r14);
                }
                        break;
-               case CEE_ENDFINALLY: {
+               case OP_ENDFINALLY: {
                        if (s390_is_uimm12 (ins->inst_left->inst_offset)) {
                                s390_l  (code, s390_r14, 0, ins->inst_left->inst_basereg,
                                         ins->inst_left->inst_offset);
@@ -3591,7 +3570,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        ins->inst_c0 = code - cfg->native_code;
                }
                        break;
-               case CEE_BR: 
+               case OP_BR: 
                        EMIT_UNCOND_BRANCH(ins);
                        break;
                case OP_BR_REG: {
@@ -3905,37 +3884,57 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_lhi   (code, ins->dreg, 0);
                }
                        break;
-               case OP_FBEQ:
-                       EMIT_COND_BRANCH (ins, S390_CC_EQ|S390_CC_OV);
+               case OP_FBEQ: {
+                       short *o;
+                       s390_jo (code, 0); CODEPTR(code, o);
+                       EMIT_COND_BRANCH (ins, S390_CC_EQ);
+                       PTRSLOT(code, o);
+               }
                        break;
                case OP_FBNE_UN:
                        EMIT_COND_BRANCH (ins, S390_CC_NE|S390_CC_OV);
                        break;
-               case OP_FBLT:
+               case OP_FBLT: {
+                       short *o;
+                       s390_jo (code, 0); CODEPTR(code, o);
                        EMIT_COND_BRANCH (ins, S390_CC_LT);
+                       PTRSLOT(code, o);
+               }
                        break;
                case OP_FBLT_UN:
                        EMIT_COND_BRANCH (ins, S390_CC_LT|S390_CC_OV);
                        break;
-               case OP_FBGT:
+               case OP_FBGT: {
+                       short *o;
+                       s390_jo (code, 0); CODEPTR(code, o);
                        EMIT_COND_BRANCH (ins, S390_CC_GT);
+                       PTRSLOT(code, o);
+               }
                        break;
                case OP_FBGT_UN:
                        EMIT_COND_BRANCH (ins, S390_CC_GT|S390_CC_OV);
                        break;
-               case OP_FBGE:
+               case OP_FBGE: {
+                       short *o;
+                       s390_jo (code, 0); CODEPTR(code, o);
                        EMIT_COND_BRANCH (ins, S390_CC_GE);
+                       PTRSLOT(code, o);
+               }
                        break;
                case OP_FBGE_UN:
                        EMIT_COND_BRANCH (ins, S390_CC_GE|S390_CC_OV);
                        break;
-               case OP_FBLE:
+               case OP_FBLE: {
+                       short *o;
+                       s390_jo (code, 0); CODEPTR(code, o);
                        EMIT_COND_BRANCH (ins, S390_CC_LE);
+                       PTRSLOT(code, o);
+               }
                        break;
                case OP_FBLE_UN:
                        EMIT_COND_BRANCH (ins, S390_CC_LE|S390_CC_OV);
                        break;
-               case CEE_CKFINITE: {
+               case OP_CKFINITE: {
                        short *o;
                        s390_lhi  (code, s390_r13, 0x7f);
                        s390_tcdb (code, ins->sreg1, 0, s390_r13, 0);
@@ -4175,7 +4174,7 @@ emit_load_volatile_registers(guint8 * code, MonoCompile *cfg)
 
        for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
                ArgInfo *ainfo = cinfo->args + i;
-               inst = cfg->varinfo [pos];
+               inst = cfg->args [pos];
                
                if (inst->opcode == OP_REGVAR) {
                        if (ainfo->regtype == RegTypeGeneral)
@@ -4319,7 +4318,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                        max_offset += 6; 
 
                while (ins) {
-                       max_offset += ((guint8 *)ins_spec [ins->opcode])[MONO_INST_LEN];
+                       max_offset += ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN];
                        ins = ins->next;
                }
        }
@@ -4339,7 +4338,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
 
        for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
                ArgInfo *ainfo = cinfo->args + i;
-               inst = cfg->varinfo [pos];
+               inst = cfg->args [pos];
                
                if (inst->opcode == OP_REGVAR) {
                        if (ainfo->regtype == RegTypeGeneral)
@@ -4603,8 +4602,7 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
                        iExc;
        guint32         code_size;
        MonoClass       *exc_classes [MAX_EXC];
-       guint8          *exc_throw_start [MAX_EXC], 
-                       *exc_throw_end [MAX_EXC];
+       guint8          *exc_throw_start [MAX_EXC];
 
        for (patch_info = cfg->patch_info; 
             patch_info; 
@@ -4898,9 +4896,9 @@ mono_arch_print_tree (MonoInst *tree, int arity)
                        done = 1;
                        break;
                case OP_S390_SETF4RET:
-                       printf ("[f%ld,f%ld]", 
-                               mono_arch_regname (tree->dreg),
-                               mono_arch_regname (tree->sreg1));
+                       printf ("[%s,%s]", 
+                               mono_arch_fregname (tree->dreg),
+                               mono_arch_fregname (tree->sreg1));
                        done = 1;
                        break;
                case OP_TLS_GET: