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