2008-10-17 Marek Safar <marek.safar@gmail.com>
[mono.git] / mono / mini / mini-hppa.c
index 0043c12f6962343aa40752695b158fdd1d398efa..becb78d86c2a0bb1291d10cdb6be3cd14871d3ff 100644 (file)
@@ -701,7 +701,10 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call,
                        arg->inst_left = in;
                        arg->inst_call = call;
                        arg->type = in->type;
-                       MONO_INST_LIST_ADD_TAIL (&arg->node, &call->out_args);
+
+                       /* prepend, we'll need to reverse them later */
+                       arg->next = call->out_args;
+                       call->out_args = arg;
 
                        switch (ainfo->storage) {
                        case ArgInIReg:
@@ -750,6 +753,19 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call,
                }
        }
 
+       /*
+        * Reverse the call->out_args list.
+        */
+       {
+               MonoInst *prev = NULL, *list = call->out_args, *next;
+               while (list) {
+                       next = list->next;
+                       list->next = prev;
+                       prev = list;
+                       list = next;
+               }
+               call->out_args = prev;
+       }
        call->stack_usage = cinfo->stack_usage;
        cfg->param_area = MAX (cfg->param_area, call->stack_usage);
        cfg->param_area = ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT);
@@ -774,10 +790,23 @@ mono_arch_peephole_pass_2 (MonoCompile *cfg, MonoBasicBlock *bb)
        DEBUG_FUNC_EXIT();
 }
 
-#define NEW_INS(cfg,ins,dest,op) do {                                  \
+static void
+insert_after_ins (MonoBasicBlock *bb, MonoInst *ins, MonoInst *to_insert)
+{
+       if (ins == NULL) {
+               ins = bb->code;
+               bb->code = to_insert;
+               to_insert->next = ins;
+       } else {
+               to_insert->next = ins->next;
+               ins->next = to_insert;
+       }
+}
+
+#define NEW_INS(cfg,dest,op) do {       \
                (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst));       \
                (dest)->opcode = (op);  \
-               MONO_INST_LIST_ADD_TAIL (&(dest)->node, &(ins)->node); \
+               insert_after_ins (bb, last_ins, (dest)); \
        } while (0)
 
 static int
@@ -856,7 +885,7 @@ map_to_reg_reg_op (int op)
 void
 mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb)
 {
-       MonoInst *ins, *next, *temp, *temp2;
+       MonoInst *ins, *next, *temp, *last_ins = NULL;
        int imm;
 
        /* setup the virtual reg allocator */
@@ -869,7 +898,7 @@ loop_start:
                case OP_ADD_IMM:
                case OP_ADDCC_IMM:
                        if (!hppa_check_bits (ins->inst_imm, 11)) {
-                               NEW_INS (cfg, ins, temp, OP_ICONST);
+                               NEW_INS (cfg, temp, OP_ICONST);
                                temp->inst_c0 = ins->inst_imm;
                                temp->dreg = mono_regstate_next_int (cfg->rs);
                                ins->sreg2 = temp->dreg;
@@ -879,7 +908,7 @@ loop_start:
                case OP_SUB_IMM:
                case OP_SUBCC_IMM:
                        if (!hppa_check_bits (ins->inst_imm, 11)) {
-                               NEW_INS (cfg, ins, temp, OP_ICONST);
+                               NEW_INS (cfg, temp, OP_ICONST);
                                temp->inst_c0 = ins->inst_imm;
                                temp->dreg = mono_regstate_next_int (cfg->rs);
                                ins->sreg2 = temp->dreg;
@@ -905,7 +934,7 @@ loop_start:
                        }
                        else {
                                int tmp = mono_regstate_next_int (cfg->rs);
-                               NEW_INS (cfg, ins, temp, OP_ICONST);
+                               NEW_INS (cfg, temp, OP_ICONST);
                                temp->inst_c0 = ins->inst_c0;
                                temp->dreg = tmp;
 
@@ -920,35 +949,35 @@ loop_start:
                        int freg1 = mono_regstate_next_float (cfg->rs);
                        int freg2 = mono_regstate_next_float (cfg->rs);
 
-                       NEW_INS(cfg, ins, temp, OP_STORE_MEMBASE_REG);
+                       NEW_INS(cfg, temp, OP_STORE_MEMBASE_REG);
                        temp->sreg1 = ins->sreg1;
                        temp->inst_destbasereg = hppa_sp;
                        temp->inst_offset = -16;
 
-                       NEW_INS(cfg, temp, temp2, OP_LOADR4_MEMBASE);
-                       temp2->dreg = freg1;
-                       temp2->inst_basereg = hppa_sp;
-                       temp2->inst_offset = -16;
+                       NEW_INS(cfg, temp, OP_LOADR4_MEMBASE);
+                       temp->dreg = freg1;
+                       temp->inst_basereg = hppa_sp;
+                       temp->inst_offset = -16;
 
-                       NEW_INS(cfg, temp2, temp, OP_STORE_MEMBASE_REG);
+                       NEW_INS(cfg, temp, OP_STORE_MEMBASE_REG);
                        temp->sreg1 = ins->sreg2;
                        temp->inst_destbasereg = hppa_sp;
                        temp->inst_offset = -16;
 
-                       NEW_INS(cfg, temp, temp2, OP_LOADR4_MEMBASE);
-                       temp2->dreg = freg2;
-                       temp2->inst_basereg = hppa_sp;
-                       temp2->inst_offset = -16;
+                       NEW_INS(cfg, temp, OP_LOADR4_MEMBASE);
+                       temp->dreg = freg2;
+                       temp->inst_basereg = hppa_sp;
+                       temp->inst_offset = -16;
 
-                       NEW_INS (cfg, temp2, temp, OP_HPPA_XMPYU);
+                       NEW_INS (cfg, temp, OP_HPPA_XMPYU);
                        temp->dreg = freg2;
                        temp->sreg1 = freg1;
                        temp->sreg2 = freg2;
 
-                       NEW_INS(cfg, temp, temp2, OP_HPPA_STORER4_RIGHT);
-                       temp2->sreg1 = freg2;
-                       temp2->inst_destbasereg = hppa_sp;
-                       temp2->inst_offset = -16;
+                       NEW_INS(cfg, temp, OP_HPPA_STORER4_RIGHT);
+                       temp->sreg1 = freg2;
+                       temp->inst_destbasereg = hppa_sp;
+                       temp->inst_offset = -16;
 
                        ins->opcode = OP_LOAD_MEMBASE;
                        ins->inst_basereg = hppa_sp;
@@ -959,7 +988,9 @@ loop_start:
                default:
                        break;
                }
+               last_ins = ins;
        }
+       bb->last_ins = last_ins;
        bb->max_vreg = cfg->rs->next_vreg;
        
 }
@@ -1221,6 +1252,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
        MonoCallInst *call;
        guint offset;
        guint32 *code = (guint32*)(cfg->native_code + cfg->code_len);
+       MonoInst *last_ins = NULL;
        int max_len, cpos;
        const char *spec;
 
@@ -1256,6 +1288,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                mono_debug_record_line_number (cfg, ins, offset);
 
                switch (ins->opcode) {
+               case OP_RELAXED_NOP:
+                       break;
                case OP_STOREI1_MEMBASE_IMM:
                        EMIT_STORE_MEMBASE_IMM (ins, stb);
                        break;
@@ -1695,6 +1729,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                case OP_BR: {
                        guint32 target;
+                       DEBUG (printf ("target: %p, next: %p, curr: %p, last: %p\n", ins->inst_target_bb, bb->next_bb, ins, bb->last_ins));
                        if (ins->flags & MONO_INST_BRLABEL) {
                                mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_LABEL, ins->inst_i0);
                        } else {
@@ -2010,6 +2045,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
               
                cpos += max_len;
+
+               last_ins = ins;
        }
 
        cfg->code_len = (guint8*)code - cfg->native_code;
@@ -2281,13 +2318,13 @@ mono_arch_emit_prolog (MonoCompile *cfg)
         */
        max_offset = 0;
        for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
-               MonoInst *ins;
+               MonoInst *ins = bb->code;
                bb->max_offset = max_offset;
 
                if (cfg->prof_options & MONO_PROFILE_COVERAGE)
                        max_offset += 6; 
 
-               MONO_BB_FOR_EACH_INS (bb, ins) {
+               MONO_BB_FOR_EACH_INS (bb, ins)
                        max_offset += ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN];
        }