Author: zoltan
Date: 2005-06-10 17:33:03 -0400 (Fri, 10 Jun 2005)
New Revision: 45796

Modified:
   trunk/mono/mono/mini/ChangeLog
   trunk/mono/mono/mini/cpu-ia64.md
   trunk/mono/mono/mini/exceptions-ia64.c
   trunk/mono/mono/mini/inssel-ia64.brg
   trunk/mono/mono/mini/mini-codegen.c
   trunk/mono/mono/mini/mini-ia64.c
Log:
2005-06-11  Zoltan Varga  <[EMAIL PROTECTED]>

        * *-ia64.*: Ongoing IA64 work.


Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog      2005-06-10 21:14:51 UTC (rev 45795)
+++ trunk/mono/mono/mini/ChangeLog      2005-06-10 21:33:03 UTC (rev 45796)
@@ -1,3 +1,7 @@
+2005-06-11  Zoltan Varga  <[EMAIL PROTECTED]>
+
+       * *-ia64.*: Ongoing IA64 work.
+
 2005-06-10  Zoltan Varga  <[EMAIL PROTECTED]>
 
        * basic-long.cs: Add tests for add/sub.ovf.

Modified: trunk/mono/mono/mini/cpu-ia64.md
===================================================================
--- trunk/mono/mono/mini/cpu-ia64.md    2005-06-10 21:14:51 UTC (rev 45795)
+++ trunk/mono/mono/mini/cpu-ia64.md    2005-06-10 21:33:03 UTC (rev 45796)
@@ -419,7 +419,7 @@
 int_sbb: dest:i src1:i src2:i len:48
 int_sbb_imm: dest:i src1:i len:48
 int_addcc: dest:i src1:i src2:i len:96
-int_subcc: dest:i src1:i src2:i len:48
+int_subcc: dest:i src1:i src2:i len:96
 int_add_imm: dest:i src1:i len:48
 int_sub_imm: dest:i src1:i len:48
 int_mul_imm: dest:i src1:i len:48
@@ -507,3 +507,4 @@
 ia64_br_cond: len:48
 ia64_cond_exc: len:48
 ia64_cset: dest:i len:48
+

Modified: trunk/mono/mono/mini/exceptions-ia64.c
===================================================================
--- trunk/mono/mono/mini/exceptions-ia64.c      2005-06-10 21:14:51 UTC (rev 
45795)
+++ trunk/mono/mono/mini/exceptions-ia64.c      2005-06-10 21:33:03 UTC (rev 
45796)
@@ -122,7 +122,7 @@
 
        start = mono_global_codeman_reserve (256);
 
-       /* call_filter (MonoContext *ctx, unsigned long eip) */
+       /* int call_filter (MonoContext *ctx, unsigned long eip) */
 
        /* FIXME: */
        ia64_codegen_init (code, start);
@@ -137,16 +137,14 @@
 }
 
 static void
-throw_exception (MonoObject *exc, guint64 ip, guint64 rethrow)
+throw_exception (MonoObject *exc, guint64 rethrow)
 {
-       static void (*restore_context) (MonoContext *);
        unw_context_t unw_ctx;
        MonoContext ctx;
+       MonoJitInfo *ji;
+       unw_word_t ip;
        int res;
 
-       if (!restore_context)
-               restore_context = mono_arch_get_restore_context ();
-
        if (mono_object_isinst (exc, mono_defaults.exception_class)) {
                MonoException *mono_ex = (MonoException*)exc;
                if (!rethrow)
@@ -158,14 +156,24 @@
        res = unw_init_local (&ctx.cursor, &unw_ctx);
        g_assert (res == 0);
 
-       /* Get rid of this frame and the throw trampoline frame */
-       res = unw_step (&ctx.cursor);
-       g_assert (res >= 0);
-       res = unw_step (&ctx.cursor);
-       g_assert (res >= 0);
+       /* 
+        * Unwind until the first managed frame. This is needed since 
+        * mono_handle_exception expects the variables in the original context 
to
+        * correspond to the method returned by mono_find_jit_info.
+        */
+       while (TRUE) {
+               res = unw_get_reg (&ctx.cursor, UNW_IA64_IP, &ip);
+               g_assert (res == 0);
 
-       unw_set_reg (&ctx.cursor, UNW_IA64_IP, (guint64)ip);
+               ji = mono_jit_info_table_find (mono_domain_get (), 
(gpointer)ip);
 
+               if (ji)
+                       break;
+
+               res = unw_step (&ctx.cursor);
+               g_assert (res >= 0);
+       }
+
        fill_monocontext_from_cursor (&ctx);
 
        mono_handle_exception (&ctx, exc, (gpointer)(ip + 1), FALSE);
@@ -208,8 +216,7 @@
 
        /* Set args */
        ia64_mov (code, out0 + 0, in0 + 0);
-       ia64_mov_from_br (code, out0 + 1, IA64_B0);
-       ia64_adds_imm (code, out0 + 2, rethrow, IA64_R0);
+       ia64_adds_imm (code, out0 + 1, rethrow, IA64_R0);
 
        /* Call throw_exception */
        ia64_movl (code, GP_SCRATCH_REG, ptr);
@@ -330,8 +337,6 @@
        out0 = local0 + 4;
        nout = 3;
 
-       /* FIXME: Add unwind info */
-
        ia64_codegen_init (code, start);
        ia64_alloc (code, local0 + 0, local0 - in0, out0 - local0, nout, 0);
        ia64_mov_from_br (code, local0 + 1, IA64_RP);
@@ -361,10 +366,12 @@
        ia64_mov (code, local0 + 2, local0 + 1);
        ia64_sub (code, local0 + 2, local0 + 2, in0 + 1);
 
+       /* Trick the unwind library into using throw_ip as the IP in the caller 
frame */
+       ia64_mov (code, local0 + 1, local0 + 2);
+
        /* Set args */
        ia64_mov (code, out0 + 0, local0 + 3);
-       ia64_mov (code, out0 + 1, local0 + 2);
-       ia64_mov (code, out0 + 2, IA64_R0);
+       ia64_mov (code, out0 + 1, IA64_R0);
 
        /* Call throw_exception */
        ptr = throw_exception;
@@ -489,11 +496,42 @@
 gboolean
 mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
 {
-       ucontext_t *ctx = (ucontext_t*)sigctx;
-       MonoContext mctx;
+       /* libunwind takes care of this */
+       unw_context_t unw_ctx;
+       MonoContext ctx;
+       MonoJitInfo *ji;
+       unw_word_t ip;
+       int res;
 
-       NOT_IMPLEMENTED;
-       return FALSE;
+       res = unw_getcontext (&unw_ctx);
+       g_assert (res == 0);
+       res = unw_init_local (&ctx.cursor, &unw_ctx);
+       g_assert (res == 0);
+
+       /* 
+        * Unwind until the first managed frame. This skips the signal handler 
frames
+        * too.
+        */
+       while (TRUE) {
+               res = unw_get_reg (&ctx.cursor, UNW_IA64_IP, &ip);
+               g_assert (res == 0);
+
+               ji = mono_jit_info_table_find (mono_domain_get (), 
(gpointer)ip);
+
+               if (ji)
+                       break;
+
+               res = unw_step (&ctx.cursor);
+               g_assert (res >= 0);
+       }
+
+       fill_monocontext_from_cursor (&ctx);
+
+       mono_handle_exception (&ctx, obj, (gpointer)ip, test_only);
+
+       restore_context (&ctx);
+
+       g_assert_not_reached ();
 }
 
 gpointer

Modified: trunk/mono/mono/mini/inssel-ia64.brg
===================================================================
--- trunk/mono/mono/mini/inssel-ia64.brg        2005-06-10 21:14:51 UTC (rev 
45795)
+++ trunk/mono/mono/mini/inssel-ia64.brg        2005-06-10 21:33:03 UTC (rev 
45796)
@@ -272,4 +272,10 @@
        mono_bblock_add_inst (s->cbb, tree);
 }
 
+reg: OP_LOCALLOC (reg) {
+       tree->sreg1 = state->left->reg1;
+       tree->dreg = state->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
 %%

Modified: trunk/mono/mono/mini/mini-codegen.c
===================================================================
--- trunk/mono/mono/mini/mini-codegen.c 2005-06-10 21:14:51 UTC (rev 45795)
+++ trunk/mono/mono/mini/mini-codegen.c 2005-06-10 21:33:03 UTC (rev 45796)
@@ -200,7 +200,7 @@
                g_error ("Unknown opcode: %s\n", mono_inst_name (ins->opcode));
 
        if (spec [MONO_INST_DEST]) {
-               gboolean fp = (spec [MONO_INST_DEST] == 'f');
+               gboolean fp = dreg_is_fp (ins);
                if (is_soft_reg (ins->dreg, fp))
                        g_print (" R%d <-", ins->dreg);
                else if (spec [MONO_INST_DEST] == 'b') {
@@ -425,6 +425,25 @@
        }
 }
 
+static void
+free_up_reg (MonoCompile *cfg, InstList *item, MonoInst *ins, int hreg, 
gboolean fp)
+{
+       if (fp) {
+               if (!(cfg->rs->ffree_mask & (1 << hreg))) {
+                       DEBUG (g_print ("\tforced spill of R%d\n", 
cfg->rs->isymbolic [hreg]));
+                       get_register_force_spilling (cfg, item, ins, 
cfg->rs->isymbolic [hreg], fp);
+                       mono_regstate_free_float (cfg->rs, hreg);
+               }
+       }
+       else {
+               if (!(cfg->rs->ifree_mask & (1 << hreg))) {
+                       DEBUG (g_print ("\tforced spill of R%d\n", 
cfg->rs->isymbolic [hreg]));
+                       get_register_force_spilling (cfg, item, ins, 
cfg->rs->isymbolic [hreg], fp);
+                       mono_regstate_free_int (cfg->rs, hreg);
+               }
+       }
+}
+
 static MonoInst*
 create_copy_ins (MonoCompile *cfg, int dest, int src, MonoInst *ins, gboolean 
fp)
 {
@@ -441,7 +460,7 @@
                copy->next = ins->next;
                ins->next = copy;
        }
-       DEBUG (g_print ("\tforced copy from %s to %s\n", mono_arch_regname 
(src), mono_arch_regname (dest)));
+       DEBUG (g_print ("\tforced copy from %s to %s\n", mono_regname_full 
(src, fp), mono_regname_full (dest, fp)));
        return copy;
 }
 
@@ -643,7 +662,7 @@
                                        fpcount--;
                        }
 
-                       if (spec [MONO_INST_DEST] == 'f') {
+                       if (dreg_is_fp (ins)) {
                                if (use_fpstack && (spec [MONO_INST_CLOB] != 
'm')) {
                                        if (fpcount >= MONO_ARCH_FPSTACK_SIZE) {
                                                reginfof [ins->dreg].flags |= 
MONO_FP_NEEDS_SPILL;
@@ -693,7 +712,7 @@
                if (spec [MONO_INST_DEST]) {
                        int dest_dreg;
 
-                       if (spec [MONO_INST_DEST] == 'f')
+                       if (dreg_is_fp (ins))
                                reginfod = reginfof;
                        else
                                reginfod = reginfo;
@@ -807,7 +826,7 @@
                 * TRACK FP STACK
                 */
                if (use_fpstack && (spec [MONO_INST_CLOB] != 'm')) {
-                       if (spec [MONO_INST_DEST] == 'f') {
+                       if (dreg_is_fp (ins)) {
                                if (reginfof [ins->dreg].flags & 
MONO_FP_NEEDS_SPILL) {
                                        GList *spill_node;
                                        MonoInst *store;
@@ -1060,8 +1079,14 @@
                        create_copy_ins (cfg, ins->dreg, dest_dreg, ins, fp);
                        ins->dreg = dest_dreg;
 
-                       if (rs->isymbolic [dest_dreg] >= MONO_MAX_IREGS)
-                               free_up_ireg (cfg, tmp, ins, dest_dreg);
+                       if (fp) {
+                               if (rs->fsymbolic [dest_dreg] >= MONO_MAX_FREGS)
+                                       free_up_reg (cfg, tmp, ins, dest_dreg, 
fp);
+                       }
+                       else {
+                               if (rs->isymbolic [dest_dreg] >= MONO_MAX_IREGS)
+                                       free_up_reg (cfg, tmp, ins, dest_dreg, 
fp);
+                       }
                }
 
                /*
@@ -1309,7 +1334,7 @@
                }
 
                /* Handle dreg==sreg1 */
-               if (((spec [MONO_INST_DEST] == 'f' && spec [MONO_INST_SRC1] == 
'f' && !use_fpstack) || spec [MONO_INST_CLOB] == '1') && ins->dreg != 
ins->sreg1) {
+               if (((dreg_is_fp (ins) && spec [MONO_INST_SRC1] == 'f' && 
!use_fpstack) || spec [MONO_INST_CLOB] == '1') && ins->dreg != ins->sreg1) {
                        MonoInst *sreg2_copy = NULL;
                        MonoInst *copy;
                        gboolean fp = (spec [MONO_INST_SRC1] == 'f');

Modified: trunk/mono/mono/mini/mini-ia64.c
===================================================================
--- trunk/mono/mono/mini/mini-ia64.c    2005-06-10 21:14:51 UTC (rev 45795)
+++ trunk/mono/mono/mini/mini-ia64.c    2005-06-10 21:33:03 UTC (rev 45796)
@@ -411,14 +411,6 @@
 void
 mono_arch_cpu_init (void)
 {
-       gint64 tmp;
-
-       /* Enable fp traps */
-       asm volatile  ("mov %0 = ar.fpsr ;;\n\t"
-                                  "dep %0 = 0, %0, 2, 1 ;;\n\t"
-                                  "dep %0 = 0, %0, 3, 1 ;;\n\t"
-                                  "mov ar.fpsr = %0 ;;\n\t"
-                                  : "=r" (tmp));
 }
 
 /*
@@ -1549,7 +1541,7 @@
                }
                case OP_MUL_IMM: {
                        /* This should be emulated, but rules in inssel.brg 
generate it */
-                       int i;
+                       int i, sum_reg;
 
                        /* First the easy cases */
                        if (ins->inst_imm == 1) {
@@ -1563,9 +1555,29 @@
                                        break;
                                }
 
+                       /* This could be optimized */
                        if (ins->opcode == OP_MUL_IMM) {
-                               /* FIXME: */
-                               g_error ("Multiplication by %ld not 
implemented\n", ins->inst_imm);
+                               sum_reg = 0;
+                               for (i = 0; i < 64; ++i) {
+                                       if (ins->inst_imm & (((gint64)1) << i)) 
{
+                                               NEW_INS (cfg, temp, OP_SHL_IMM);
+                                               temp->dreg = 
mono_regstate_next_int (cfg->rs);
+                                               temp->sreg1 = ins->sreg1;
+                                               temp->inst_imm = i;
+
+                                               if (sum_reg == 0)
+                                                       sum_reg = temp->dreg;
+                                               else {
+                                                       NEW_INS (cfg, temp2, 
CEE_ADD);
+                                                       temp2->dreg = 
mono_regstate_next_int (cfg->rs);
+                                                       temp2->sreg1 = sum_reg;
+                                                       temp2->sreg2 = 
temp->dreg;
+                                                       sum_reg = temp2->dreg;
+                                               }
+                                       }
+                               }
+                               ins->opcode = OP_MOVE;
+                               ins->sreg1 = sum_reg;
                        }
                        break;
                }
@@ -1740,9 +1752,9 @@
        while (ins) {
                offset = code.buf - cfg->native_code;
 
-               max_len = ((int)(((guint8 *)ins_spec 
[ins->opcode])[MONO_INST_LEN]));
+               max_len = ((int)(((guint8 *)ins_spec 
[ins->opcode])[MONO_INST_LEN])) + 128;
 
-               if (offset > (cfg->code_size - max_len - 16)) {
+               while (offset + max_len + 16 > cfg->code_size) {
                        ia64_codegen_close (code);
 
                        offset = code.buf - cfg->native_code;
@@ -1797,6 +1809,8 @@
                        ia64_begin_bundle (code);
                        ins->inst_c0 = code.buf - cfg->native_code;
                        break;
+               case CEE_NOP:
+                       break;
                case OP_BR_REG:
                        ia64_mov_to_br (code, IA64_B6, ins->sreg1);
                        ia64_br_cond_reg (code, IA64_B6);
@@ -1860,10 +1874,58 @@
                        /* (sreg2 <= 0) && (res > ins->sreg1) => signed 
overflow */
                        ia64_cmp4_lt_pred (code, 9, 6, 10, ins->sreg1, 
GP_SCRATCH_REG);
 
+                       /* res <u sreg1 => unsigned overflow */
+                       ia64_cmp4_ltu (code, 7, 10, GP_SCRATCH_REG, ins->sreg1);
+
+                       /* FIXME: Predicate this since this is a side effect */
                        ia64_mov (code, ins->dreg, GP_SCRATCH_REG);
+                       break;
+               case OP_ISUBCC:
+                       /* p6 and p7 is set if there is signed/unsigned 
overflow */
+                       
+                       /* Set p8-p9 == (sreg2 > 0) */
+                       ia64_cmp4_lt (code, 8, 9, IA64_R0, ins->sreg2);
 
-                       /* FIXME: Set p7 as well */
+                       ia64_sub (code, GP_SCRATCH_REG, ins->sreg1, ins->sreg2);
+                       
+                       /* (sreg2 > 0) && (res > ins->sreg1) => signed overflow 
*/
+                       ia64_cmp4_gt_pred (code, 8, 6, 10, GP_SCRATCH_REG, 
ins->sreg1);
+                       /* (sreg2 <= 0) && (res < ins->sreg1) => signed 
overflow */
+                       ia64_cmp4_lt_pred (code, 9, 6, 10, GP_SCRATCH_REG, 
ins->sreg1);
+
+                       /* sreg1 <u sreg2 => unsigned overflow */
+                       ia64_cmp4_ltu (code, 7, 10, ins->sreg1, ins->sreg2);
+
+                       /* FIXME: Predicate this since this is a side effect */
+                       ia64_mov (code, ins->dreg, GP_SCRATCH_REG);
                        break;
+               case OP_ADDCC:
+                       /* Same as OP_IADDCC */
+                       ia64_cmp_lt (code, 8, 9, IA64_R0, ins->sreg2);
+
+                       ia64_add (code, GP_SCRATCH_REG, ins->sreg1, ins->sreg2);
+                       
+                       ia64_cmp_lt_pred (code, 8, 6, 10, GP_SCRATCH_REG, 
ins->sreg1);
+                       ia64_cmp_lt_pred (code, 9, 6, 10, ins->sreg1, 
GP_SCRATCH_REG);
+
+                       ia64_cmp_ltu (code, 7, 10, GP_SCRATCH_REG, ins->sreg1);
+
+                       ia64_mov (code, ins->dreg, GP_SCRATCH_REG);
+                       break;
+               case OP_SUBCC:
+                       /* Same as OP_ISUBCC */
+
+                       ia64_cmp_lt (code, 8, 9, IA64_R0, ins->sreg2);
+
+                       ia64_sub (code, GP_SCRATCH_REG, ins->sreg1, ins->sreg2);
+                       
+                       ia64_cmp_gt_pred (code, 8, 6, 10, GP_SCRATCH_REG, 
ins->sreg1);
+                       ia64_cmp_lt_pred (code, 9, 6, 10, GP_SCRATCH_REG, 
ins->sreg1);
+
+                       ia64_cmp_ltu (code, 7, 10, ins->sreg1, ins->sreg2);
+
+                       ia64_mov (code, ins->dreg, GP_SCRATCH_REG);
+                       break;
                case OP_ADD_IMM:
                case OP_IADD_IMM:
                        ia64_adds_imm (code, ins->dreg, ins->inst_imm, 
ins->sreg1);
@@ -2111,12 +2173,16 @@
                        break;
 
                case OP_COND_EXC_IOV:
-                       /* FIXME: */
-                       ia64_break_i_pred (code, 6, 0);
+               case OP_COND_EXC_OV:
+                       mono_add_patch_info (cfg, code.buf - cfg->native_code,
+                                                                
MONO_PATCH_INFO_EXC, "OverflowException");
+                       ia64_br_cond_pred (code, 6, 0);
                        break;
                case OP_COND_EXC_IC:
-                       /* FIXME: */
-                       ia64_break_i_pred (code, 7, 0);
+               case OP_COND_EXC_C:
+                       mono_add_patch_info (cfg, code.buf - cfg->native_code,
+                                                                
MONO_PATCH_INFO_EXC, "OverflowException");
+                       ia64_br_cond_pred (code, 7, 0);
                        break;
                case OP_IA64_COND_EXC:
                        mono_add_patch_info (cfg, code.buf - cfg->native_code,
@@ -2292,6 +2358,31 @@
                        code = emit_move_return_value (cfg, ins, code);
                        break;
 
+               case OP_LOCALLOC:
+                       /* keep alignment */
+                       ia64_adds_imm (code, GP_SCRATCH_REG, 
MONO_ARCH_FRAME_ALIGNMENT - 1, ins->sreg1);
+                       ia64_movl (code, GP_SCRATCH_REG2, 
~(MONO_ARCH_FRAME_ALIGNMENT - 1));
+                       ia64_and (code, GP_SCRATCH_REG, GP_SCRATCH_REG, 
GP_SCRATCH_REG2);
+
+                       ia64_sub (code, IA64_SP, IA64_SP, GP_SCRATCH_REG);
+
+                       /* The first 16 bytes at sp are reserved by the ABI */
+                       ia64_adds_imm (code, ins->dreg, 16, IA64_SP);
+
+                       if (ins->flags & MONO_INST_INIT) {
+                               /* Upper limit */
+                               ia64_add (code, GP_SCRATCH_REG2, ins->dreg, 
GP_SCRATCH_REG);
+
+                               /* Init loop */
+                               ia64_st8_inc_imm_hint (code, ins->dreg, 
IA64_R0, 8, 0);
+                               ia64_cmp_lt (code, 8, 9, ins->dreg, 
GP_SCRATCH_REG2);
+                               ia64_br_cond_pred (code, 8, -2);
+
+                               ia64_sub (code, ins->dreg, GP_SCRATCH_REG2, 
GP_SCRATCH_REG);
+                       }
+
+                       break;
+
                        /* Exception handling */
                case OP_CALL_HANDLER:
                        /*
@@ -2339,6 +2430,11 @@
                        code = emit_call (cfg, code, 
MONO_PATCH_INFO_INTERNAL_METHOD, 
                                                          
(gpointer)"mono_arch_throw_exception");
                        break;
+               case OP_RETHROW:
+                       ia64_mov (code, cfg->arch.reg_out0, ins->sreg1);
+                       code = emit_call (cfg, code, 
MONO_PATCH_INFO_INTERNAL_METHOD, 
+                                                         
(gpointer)"mono_arch_rethrow_exception");
+                       break;
 
                default:
                        g_warning ("unknown opcode %s in %s()\n", 
mono_inst_name (ins->opcode), __FUNCTION__);
@@ -2997,7 +3093,7 @@
 void
 mono_arch_flush_register_windows (void)
 {
-       NOT_IMPLEMENTED;
+       /* Not needed because of libunwind */
 }
 
 gboolean 
@@ -3015,8 +3111,7 @@
 gboolean
 mono_arch_is_int_overflow (void *sigctx, void *info)
 {
-       NOT_IMPLEMENTED;
-
+       /* Division is emulated with explicit overflow checks */
        return FALSE;
 }
 

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to