2007-05-27 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / mini-s390x.c
index 02d56d3d86108e31d51b84dc811f5f650502b587..c5afe7ac74b60d4c4688538e7476b405639a1763 100644 (file)
@@ -202,25 +202,6 @@ typedef struct {
              retStruct;
 } size_data;   
 
-typedef enum {
-       CMP_EQ,
-       CMP_NE,
-       CMP_LE,
-       CMP_GE,
-       CMP_LT,
-       CMP_GT,
-       CMP_LE_UN,
-       CMP_GE_UN,
-       CMP_LT_UN,
-       CMP_GT_UN
-} CompRelation;
-
-typedef enum {
-       CMP_TYPE_L,
-       CMP_TYPE_I,
-       CMP_TYPE_F
-} CompType;
-
 /*------------------------------------------------------------------*/
 /* Used by the instrument_emit_epilog                              */
 /*------------------------------------------------------------------*/
@@ -312,8 +293,6 @@ static int indent_level = 0;
 
 int has_ld = 0;
 
-static const char*const * ins_spec = s390x_cpu_desc;
-
 static gboolean tls_offset_inited = FALSE;
 
 static int appdomain_tls_offset = -1,
@@ -1121,6 +1100,8 @@ is_regsize_var (MonoType *t) {
        case MONO_TYPE_I8:
        case MONO_TYPE_U8:
        case MONO_TYPE_U:
+       case MONO_TYPE_PTR:
+       case MONO_TYPE_FNPTR:
                return TRUE;
        case MONO_TYPE_OBJECT:
        case MONO_TYPE_STRING:
@@ -1394,8 +1375,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)
@@ -1724,7 +1705,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;
@@ -1743,7 +1724,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 :
@@ -2309,14 +2290,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 {
-                                       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:
@@ -2324,14 +2299,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:
@@ -2491,7 +2460,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;
@@ -2604,7 +2573,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;
                case OP_LOADI1_MEMBASE: {
-                       S390_LONG (code, lb, lb, ins->dreg, 0, 
+                       S390_LONG (code, lgb, lgb, ins->dreg, 0, 
                                   ins->inst_basereg, ins->inst_offset);
                }
                        break;
@@ -2720,7 +2689,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        }
                }
                        break;
-               case CEE_BREAK: {
+               case OP_BREAK: {
                        s390_basr  (code, s390_r13, 0);
                        s390_j     (code, 6);
                        mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_ABS, 
@@ -2759,34 +2728,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        }
                }
                        break;
-//             case OP_ADDCC_IMM: {
-//                     if ((ins->next) &&
-//                         (ins->next->opcode == OP_ADC_IMM)) {
-//                             s390_basr (code, s390_r13, 0);
-//                             s390_j    (code, 6);
-//                             s390_llong(code, ins->inst_imm);
-//                             if (ins->dreg != ins->sreg1) {
-//                                     s390_lgr  (code, ins->dreg, ins->sreg1);
-//                             }
-//                             s390_alg  (code, ins->dreg, 0, s390_r13, 4);
-//                     } else {
-//                             if (s390_is_imm16 (ins->inst_imm)) {
-//                                     if (ins->dreg != ins->sreg1) {
-//                                             s390_lgr  (code, ins->dreg, ins->sreg1);
-//                                     }
-//                                     s390_aghi (code, ins->dreg, ins->inst_imm);
-//                             } else {
-//                                     s390_basr (code, s390_r13, 0);
-//                                     s390_j    (code, 6);
-//                                     s390_llong(code, ins->inst_imm);
-//                                     if (ins->dreg != ins->sreg1) {
-//                                             s390_lgr  (code, ins->dreg, ins->sreg1);
-//                                     }
-//                                     s390_ag   (code, ins->dreg, 0, s390_r13, 4);
-//                             }
-//                     }
-//             }
-//                     break;
                case OP_ADC_IMM: {
                        if (ins->dreg != ins->sreg1) {
                                s390_lgr  (code, ins->dreg, ins->sreg1);
@@ -3568,7 +3509,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);
 
@@ -3729,7 +3670,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_br  (code, s390_r14);
                }
                        break;
-               case CEE_THROW: {
+               case OP_THROW: {
                        s390_lgr  (code, s390_r2, ins->sreg1);
                        s390_basr (code, s390_r13, 0);
                        s390_j    (code, 6);
@@ -3766,7 +3707,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_br  (code, s390_r14);
                }
                        break;
-               case CEE_ENDFINALLY: {
+               case OP_ENDFINALLY: {
                        S390_LONG (code, lg, lg, s390_r14, 0, 
                                   ins->inst_left->inst_basereg, 
                                   ins->inst_left->inst_offset);
@@ -3783,7 +3724,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: {
@@ -4091,37 +4032,57 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_lghi  (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);
@@ -4385,7 +4346,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)
@@ -4408,7 +4369,7 @@ emit_load_volatile_registers (guint8 *code, MonoCompile *cfg)
                                        g_assert_not_reached();
                                switch (ainfo->size) {
                                case 1:
-                                       s390_icy  (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+                                       s390_llgc (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
                                        break;
                                case 2:
                                        s390_lgh  (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
@@ -4432,7 +4393,7 @@ emit_load_volatile_registers (guint8 *code, MonoCompile *cfg)
                                if (ainfo->reg != STK_BASE) {
                                        switch (ainfo->size) {
                                        case 1:
-                                               s390_icy (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+                                               s390_llgc (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
                                                break;
                                        case 2:
                                                s390_lgh (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
@@ -4535,7 +4496,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;
                }
        }
@@ -4555,7 +4516,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)
@@ -4816,8 +4777,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;