Author: zoltan
Date: 2008-02-15 07:16:38 -0500 (Fri, 15 Feb 2008)
New Revision: 95743
Modified:
branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog
branches/vargaz/mini-linear-il/mono/mono/mini/cpu-arm.md
branches/vargaz/mini-linear-il/mono/mono/mini/exceptions-arm.c
branches/vargaz/mini-linear-il/mono/mono/mini/mini-arm.c
Log:
2008-02-15 Zoltan Varga <[EMAIL PROTECTED]>
* exceptions-arm.c mini-arm.c cpu-arm.md: Fix arm build.
Modified: branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog 2008-02-15
12:12:53 UTC (rev 95742)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog 2008-02-15
12:16:38 UTC (rev 95743)
@@ -1,5 +1,7 @@
2008-02-15 Zoltan Varga <[EMAIL PROTECTED]>
+ * exceptions-arm.c mini-arm.c cpu-arm.md: Fix arm build.
+
* method-to-ir.c (mini_emit_inst_for_method): Fix 64 bit issues in
array access
implementation.
(mini_emit_ldelema_1_ins): Ditto.
Modified: branches/vargaz/mini-linear-il/mono/mono/mini/cpu-arm.md
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/cpu-arm.md 2008-02-15
12:12:53 UTC (rev 95742)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/cpu-arm.md 2008-02-15
12:16:38 UTC (rev 95743)
@@ -11,8 +11,9 @@
# src1:register describes the first source register of an instruction
# src2:register describes the second source register of an instruction
#
+# register may have the following values:
# i integer register
-# a r0 register (output from calls)
+# a r3 register (output from calls)
# b base register (used in address references)
# f floating point register
# g floating point register returned in r0:r1 for soft-float mode
@@ -24,12 +25,14 @@
#
# clob:spec describe if the instruction clobbers registers or has
special needs
#
+# spec can be one of the following characters:
# c clobbers caller-save registers
# r 'reserves' the destination register until a later instruction
unreserves it
# used mostly to set output registers in function calls
#
# flags:spec describe if the instruction uses or sets the flags (unused)
#
+# spec can be one of the following chars:
# s sets the flags
# u uses the flags
# m uses and modifies the flags
@@ -43,164 +46,55 @@
#
# See the code in mini-x86.c for more details on how the specifiers are used.
#
-label: len:0
-nop: len:0
-dummy_use: len:0
-dummy_store: len:0
-not_reached: len:0
-not_null: src1:i len:0
memory_barrier: len:4
-break: len:32
+nop: len:4
+break: len:4
jmp: len:92
br: len:4
-<<<<<<< .working
-br_reg: src1:i len:8
-
-int_beq: len:8
-int_bge: len:8
-int_bgt: len:8
-int_ble: len:8
-int_blt: len:8
-int_bne_un: len:8
-int_bge_un: len:8
-int_bgt_un: len:8
-int_ble_un: len:8
-int_blt_un: len:8
-
-=======
->>>>>>> .merge-right.r95529
switch: src1:i len:8
-<<<<<<< .working
-int_add: dest:i src1:i src2:i len:4
-int_sub: dest:i src1:i src2:i len:4
-int_mul: dest:i src1:i src2:i len:4
-int_div: dest:i src1:i src2:i len:40
-int_div_un: dest:i src1:i src2:i len:16
-int_rem: dest:i src1:i src2:i len:48
-int_rem_un: dest:i src1:i src2:i len:24
-int_and: dest:i src1:i src2:i len:4
-int_or: dest:i src1:i src2:i len:4
-int_xor: dest:i src1:i src2:i len:4
-int_shl: dest:i src1:i src2:i len:4
-int_shr: dest:i src1:i src2:i len:4
-int_shr_un: dest:i src1:i src2:i len:4
-
-int_neg: dest:i src1:i len:4
-int_not: dest:i src1:i len:4
-int_conv_to_i1: dest:i src1:i len:8
-int_conv_to_i2: dest:i src1:i len:8
-int_conv_to_i4: dest:i src1:i len:4
-int_conv_to_r4: dest:f src1:i len:36
-int_conv_to_r8: dest:f src1:i len:36
-int_conv_to_u4: dest:i src1:i
-int_conv_to_r_un: dest:f src1:i len:56
-int_conv_to_u2: dest:i src1:i len:8
-int_conv_to_u1: dest:i src1:i len:4
-int_conv_to_i: dest:i src1:i len:4
-
-=======
-
->>>>>>> .merge-right.r95529
throw: src1:i len:24
rethrow: src1:i len:20
-<<<<<<< .working
-
-ckfinite: dest:f src1:f len:24
-
-add.ovf: dest:i src1:i src2:i len:16
-add.ovf.un: dest:i src1:i src2:i len:16
-mul.ovf: dest:i src1:i src2:i len:16
-# this opcode is handled specially in the code generator
-mul.ovf.un: dest:i src1:i src2:i len:16
-sub.ovf: dest:i src1:i src2:i len:16
-sub.ovf.un: dest:i src1:i src2:i len:16
-add_ovf_carry: dest:i src1:i src2:i len:16
-sub_ovf_carry: dest:i src1:i src2:i len:16
-add_ovf_un_carry: dest:i src1:i src2:i len:16
-sub_ovf_un_carry: dest:i src1:i src2:i len:16
-=======
->>>>>>> .merge-right.r95529
-
-int_add_ovf: dest:i src1:i src2:i len:16
-int_add_ovf_un: dest:i src1:i src2:i len:16
-int_mul_ovf: dest:i src1:i src2:i len:16
-# this opcode is handled specially in the code generator
-int_mul_ovf_un: dest:i src1:i src2:i len:16
-int_sub_ovf: dest:i src1:i src2:i len:16
-int_sub_ovf_un: dest:i src1:i src2:i len:16
-
start_handler: len:20
endfinally: len:20
-<<<<<<< .working
call_handler: len:12
endfilter: src1:i len:16
-conv.u: dest:i src1:i len:4
-=======
-call_handler: len:12
-endfilter: src1:i len:16
-
ckfinite: dest:f src1:f len:24
->>>>>>> .merge-right.r95529
-
ceq: dest:i len:12
cgt: dest:i len:12
cgt.un: dest:i len:12
clt: dest:i len:12
clt.un: dest:i len:12
-
-int_ceq: dest:i len:12
-int_cgt: dest:i len:12
-int_cgt_un: dest:i len:12
-int_clt: dest:i len:12
-int_clt_un: dest:i len:12
-
localloc: dest:i src1:i len:60
-
compare: src1:i src2:i len:4
-icompare: src1:i src2:i len:4
-fcompare: src1:f src2:f len:12
compare_imm: src1:i len:12
-icompare_imm: src1:i len:12
+fcompare: src1:f src2:f len:12
oparglist: src1:i len:12
outarg: src1:i len:1
outarg_imm: len:16
setret: dest:a src1:i len:4
setlret: src1:i src2:i len:12
checkthis: src1:b len:4
-<<<<<<< .working
-
call: dest:a clob:c len:20
call_reg: dest:a src1:i len:8 clob:c
call_membase: dest:a src1:b len:12 clob:c
-=======
-call: dest:a clob:c len:20
-call_reg: dest:a src1:i len:8 clob:c
-call_membase: dest:a src1:b len:12 clob:c
->>>>>>> .merge-right.r95529
voidcall: len:20 clob:c
voidcall_reg: src1:i len:8 clob:c
voidcall_membase: src1:b len:12 clob:c
-fcall: dest:g len:24 clob:c
-fcall_reg: dest:g src1:i len:12 clob:c
-fcall_membase: dest:g src1:b len:16 clob:c
+fcall: dest:g len:20 clob:c
+fcall_reg: dest:g src1:i len:8 clob:c
+fcall_membase: dest:g src1:b len:12 clob:c
lcall: dest:l len:20 clob:c
lcall_reg: dest:l src1:i len:8 clob:c
lcall_membase: dest:l src1:b len:12 clob:c
vcall: len:20 clob:c
vcall_reg: src1:i len:8 clob:c
vcall_membase: src1:b len:12 clob:c
-<<<<<<< .working
-vcall2: len:20 clob:c
-vcall2_reg: src1:i len:8 clob:c
-vcall2_membase: src1:b len:12 clob:c
-
-=======
->>>>>>> .merge-right.r95529
iconst: dest:i len:16
r4const: dest:f len:20
r8const: dest:f len:20
+label: len:0
store_membase_imm: dest:b len:20
store_membase_reg: dest:b src1:i len:20
storei1_membase_imm: dest:b len:20
@@ -212,7 +106,7 @@
storei8_membase_imm: dest:b
storei8_membase_reg: dest:b src1:i
storer4_membase_reg: dest:b src1:f len:12
-storer8_membase_reg: dest:b src1:f len:32
+storer8_membase_reg: dest:b src1:f len:12
store_memindex: dest:b src1:i src2:i len:4
storei1_memindex: dest:b src1:i src2:i len:4
storei2_memindex: dest:b src1:i src2:i len:4
@@ -226,7 +120,7 @@
loadu4_membase: dest:i src1:b len:4
loadi8_membase: dest:i src1:b
loadr4_membase: dest:f src1:b len:4
-loadr8_membase: dest:f src1:b len:32
+loadr8_membase: dest:f src1:b len:4
load_memindex: dest:i src1:b src2:i len:4
loadi1_memindex: dest:i src1:b src2:i len:4
loadu1_memindex: dest:i src1:b src2:i len:4
@@ -237,7 +131,6 @@
loadu4_mem: dest:i len:8
move: dest:i src1:i len:4
fmove: dest:f src1:f len:4
-
add_imm: dest:i src1:i len:12
sub_imm: dest:i src1:i len:12
mul_imm: dest:i src1:i len:12
@@ -251,24 +144,6 @@
shl_imm: dest:i src1:i len:8
shr_imm: dest:i src1:i len:8
shr_un_imm: dest:i src1:i len:8
-
-int_add_imm: dest:i src1:i len:12
-int_sub_imm: dest:i src1:i len:12
-int_mul_imm: dest:i src1:i len:12
-# there is no actual support for division or reminder by immediate
-# we simulate them, though (but we need to change the burg rules
-# to allocate a symbolic reg for src2)
-int_div_imm: dest:i src1:i src2:i len:20
-int_div_un_imm: dest:i src1:i src2:i len:12
-int_rem_imm: dest:i src1:i src2:i len:28
-int_rem_un_imm: dest:i src1:i src2:i len:16
-int_and_imm: dest:i src1:i len:12
-int_or_imm: dest:i src1:i len:12
-int_xor_imm: dest:i src1:i len:12
-int_shl_imm: dest:i src1:i len:8
-int_shr_imm: dest:i src1:i len:8
-int_shr_un_imm: dest:i src1:i len:8
-
cond_exc_eq: len:8
cond_exc_ne_un: len:8
cond_exc_lt: len:8
@@ -283,40 +158,16 @@
cond_exc_no: len:8
cond_exc_c: len:12
cond_exc_nc: len:8
-<<<<<<< .working
-
-cond_exc_ieq: len:8
-cond_exc_ine_un: len:8
-cond_exc_ilt: len:8
-cond_exc_ilt_un: len:8
-cond_exc_igt: len:8
-cond_exc_igt_un: len:8
-cond_exc_ige: len:8
-cond_exc_ige_un: len:8
-cond_exc_ile: len:8
-cond_exc_ile_un: len:8
-cond_exc_iov: len:12
-cond_exc_ino: len:8
-cond_exc_ic: len:12
-cond_exc_inc: len:8
-
-long_conv_to_ovf_i: dest:i src1:i src2:i len:30
-long_conv_to_ovf_i4_2: dest:i src1:i src2:i len:30
-long_conv_to_r_un: dest:f src1:i src2:i len:37
-=======
->>>>>>> .merge-right.r95529
-
-float_beq: src1:f src2:f len:20
-float_bne_un: src1:f src2:f len:20
-float_blt: src1:f src2:f len:20
-float_blt_un: src1:f src2:f len:20
-float_bgt: src1:f src2:f len:20
-float_bgt_un: src1:f src2:f len:20
-float_bge: src1:f src2:f len:20
-float_bge_un: src1:f src2:f len:20
-float_ble: src1:f src2:f len:20
-float_ble_un: src1:f src2:f len:20
-
+#float_beq: src1:f src2:f len:20
+#float_bne_un: src1:f src2:f len:20
+#float_blt: src1:f src2:f len:20
+#float_blt_un: src1:f src2:f len:20
+#float_bgt: src1:f src2:f len:20
+#float_bgt_un: src1:f src2:f len:20
+#float_bge: src1:f src2:f len:20
+#float_bge_un: src1:f src2:f len:20
+#float_ble: src1:f src2:f len:20
+#float_ble_un: src1:f src2:f len:20
float_add: dest:f src1:f src2:f len:4
float_sub: dest:f src1:f src2:f len:4
float_mul: dest:f src1:f src2:f len:4
@@ -342,13 +193,8 @@
float_clt: dest:i src1:f src2:f len:16
float_clt_un: dest:i src1:f src2:f len:20
float_conv_to_u: dest:i src1:f len:36
-<<<<<<< .working
-
-=======
->>>>>>> .merge-right.r95529
aot_const: dest:i len:16
sqrt: dest:f src1:f len:4
-
adc: dest:i src1:i src2:i len:4
addcc: dest:i src1:i src2:i len:4
subcc: dest:i src1:i src2:i len:4
@@ -357,14 +203,7 @@
subcc_imm: dest:i src1:i len:12
sbb: dest:i src1:i src2:i len:4
sbb_imm: dest:i src1:i len:12
-
-int_adc: dest:i src1:i src2:i len:4
-int_addcc: dest:i src1:i src2:i len:4
-int_subcc: dest:i src1:i src2:i len:4
-int_adc_imm: dest:i src1:i len:12
-int_sbb: dest:i src1:i src2:i len:4
-int_sbb_imm: dest:i src1:i len:12
-
+br_reg: src1:i len:8
bigmul: len:8 dest:l src1:i src2:i
bigmul_un: len:8 dest:l src1:i src2:i
tls_get: len:8 dest:i
@@ -419,3 +258,72 @@
arm_rsbs_imm: dest:i src1:i len:4
arm_rsc_imm: dest:i src1:i len:4
+
+# Linear IR opcodes
+dummy_use: len:0
+dummy_store: len:0
+not_reached: len:0
+not_null: src1:i len:0
+
+int_adc: dest:i src1:i src2:i len:4
+int_addcc: dest:i src1:i src2:i len:4
+int_subcc: dest:i src1:i src2:i len:4
+int_sbb: dest:i src1:i src2:i len:4
+int_adc_imm: dest:i src1:i len:12
+int_sbb_imm: dest:i src1:i len:12
+
+int_add_imm: dest:i src1:i len:12
+int_sub_imm: dest:i src1:i len:12
+int_mul_imm: dest:i src1:i len:12
+int_div_imm: dest:i src1:i len:20
+int_div_un_imm: dest:i src1:i len:12
+int_rem_imm: dest:i src1:i len:28
+int_rem_un_imm: dest:i src1:i len:16
+int_and_imm: dest:i src1:i len:12
+int_or_imm: dest:i src1:i len:12
+int_xor_imm: dest:i src1:i len:12
+int_shl_imm: dest:i src1:i len:8
+int_shr_imm: dest:i src1:i len:8
+int_shr_un_imm: dest:i src1:i len:8
+
+int_ceq: dest:i len:12
+int_cgt: dest:i len:12
+int_cgt_un: dest:i len:12
+int_clt: dest:i len:12
+int_clt_un: dest:i len:12
+
+cond_exc_ieq: len:8
+cond_exc_ine_un: len:8
+cond_exc_ilt: len:8
+cond_exc_ilt_un: len:8
+cond_exc_igt: len:8
+cond_exc_igt_un: len:8
+cond_exc_ige: len:8
+cond_exc_ige_un: len:8
+cond_exc_ile: len:8
+cond_exc_ile_un: len:8
+cond_exc_iov: len:12
+cond_exc_ino: len:8
+cond_exc_ic: len:12
+cond_exc_inc: len:8
+
+icompare: src1:i src2:i len:4
+icompare_imm: src1:i len:12
+
+long_conv_to_ovf_i4_2: dest:i src1:i src2:i len:30
+
+vcall2: len:20 clob:c
+vcall2_reg: src1:i len:8 clob:c
+vcall2_membase: src1:b len:12 clob:c
+
+# This is different from the original JIT opcodes
+float_beq: len:20
+float_bne_un: len:20
+float_blt: len:20
+float_blt_un: len:20
+float_bgt: len:20
+float_bgt_un: len:20
+float_bge: len:20
+float_bge_un: len:20
+float_ble: len:20
+float_ble_un: len:20
Modified: branches/vargaz/mini-linear-il/mono/mono/mini/exceptions-arm.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/exceptions-arm.c
2008-02-15 12:12:53 UTC (rev 95742)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/exceptions-arm.c
2008-02-15 12:16:38 UTC (rev 95743)
@@ -25,8 +25,6 @@
#include "mini.h"
#include "mini-arm.h"
-static gboolean arch_handle_exception (MonoContext *ctx, gpointer obj,
gboolean test_only);
-
/*
struct sigcontext {
@@ -219,11 +217,11 @@
* Returns a function pointer which can be used to raise
* exceptions. The returned function has the following
* signature: void (*func) (MonoException *exc); or
- * void (*func) (char *exc_name);
+ * void (*func) (guint32 ex_token, guint8* ip);
*
*/
static gpointer
-mono_arch_get_throw_exception_generic (guint8 *start, int size, int by_name,
gboolean rethrow)
+mono_arch_get_throw_exception_generic (guint8 *start, int size, int by_token,
gboolean rethrow)
{
guint8 *code;
int alloc_size, pos, i;
@@ -234,24 +232,26 @@
ARM_MOV_REG_REG (code, ARMREG_IP, ARMREG_SP);
ARM_PUSH (code, MONO_ARM_REGSAVE_MASK);
- if (by_name) {
- /* r0 has the name of the exception: get the object */
- ARM_MOV_REG_REG (code, ARMREG_R2, ARMREG_R0);
+ if (by_token) {
+ /* r0 has the type token of the exception: get the object */
+ ARM_PUSH1 (code, ARMREG_R1);
+ ARM_MOV_REG_REG (code, ARMREG_R1, ARMREG_R0);
code = mono_arm_emit_load_imm (code, ARMREG_R0,
GPOINTER_TO_UINT (mono_defaults.corlib));
- code = mono_arm_emit_load_imm (code, ARMREG_R1,
GPOINTER_TO_UINT ("System"));
- code = mono_arm_emit_load_imm (code, ARMREG_IP,
GPOINTER_TO_UINT (mono_exception_from_name));
+ code = mono_arm_emit_load_imm (code, ARMREG_IP,
GPOINTER_TO_UINT (mono_exception_from_token));
ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC);
ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_IP);
+ ARM_POP1 (code, ARMREG_R1);
}
/* call throw_exception (exc, ip, sp, int_regs, fp_regs) */
/* caller sp */
ARM_ADD_REG_IMM8 (code, ARMREG_R2, ARMREG_SP, 10 * 4); /* 10 saved regs
*/
/* exc is already in place in r0 */
- if (by_name)
- ARM_LDR_IMM (code, ARMREG_R1, ARMREG_SP, 9 * 4); /* pos on the
stack were lr was saved */
- else
+ if (by_token) {
+ /* The caller ip is already in R1 */
+ } else {
ARM_MOV_REG_REG (code, ARMREG_R1, ARMREG_LR); /* caller ip */
+ }
/* FIXME: pointer to the saved fp regs */
/*pos = alloc_size - sizeof (double) * MONO_SAVED_FREGS;
ppc_addi (code, ppc_r7, ppc_sp, pos);*/
@@ -315,20 +315,37 @@
return start;
}
+gpointer
+mono_arch_get_throw_exception_by_name (void)
+{
+ static guint8* start;
+ static gboolean inited = FALSE;
+ guint8 *code;
+
+ if (inited)
+ return start;
+
+ start = code = mono_global_codeman_reserve (64);
+
+ /* Not used on ARM */
+ ARM_DBRK (code);
+
+ return start;
+}
+
/**
- * arch_get_throw_exception_by_name:
+ * mono_arch_get_throw_corlib_exception:
*
* Returns a function pointer which can be used to raise
* corlib exceptions. The returned function has the following
- * signature: void (*func) (char *exc_name);
- * For example to raise an arithmetic exception you can use:
- *
- * x86_push_imm (code, "ArithmeticException");
- * x86_call_code (code, arch_get_throw_exception_by_name ());
- *
+ * signature: void (*func) (guint32 ex_token, guint32 offset);
+ * Here, offset is the offset which needs to be substracted from the caller IP
+ * to get the IP of the throw. Passing the offset has the advantage that it
+ * needs no relocations in the caller.
+ * On ARM, the ip is passed instead of an offset.
*/
gpointer
-mono_arch_get_throw_exception_by_name (void)
+mono_arch_get_throw_corlib_exception (void)
{
static guint8 start [168];
static int inited = 0;
Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini-arm.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini-arm.c 2008-02-15
12:12:53 UTC (rev 95742)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini-arm.c 2008-02-15
12:16:38 UTC (rev 95743)
@@ -1234,6 +1234,10 @@
MONO_ADD_INS (cfg->cbb, ins);
mono_call_inst_add_outarg_reg (cfg, call,
ins->dreg, ainfo->reg + 1, FALSE);
} else if (!t->byref && ((t->type == MONO_TYPE_R8) ||
(t->type == MONO_TYPE_R4))) {
+#ifndef MONO_ARCH_SOFT_FLOAT
+ int creg;
+#endif
+
if (ainfo->size == 4) {
#ifdef MONO_ARCH_SOFT_FLOAT
/* mono_emit_call_args () have already
done the r8->r4 conversion */
@@ -1244,8 +1248,6 @@
MONO_ADD_INS (cfg->cbb, ins);
mono_call_inst_add_outarg_reg (cfg,
call, ins->dreg, ainfo->reg, FALSE);
#else
- int creg;
-
MONO_EMIT_NEW_STORE_MEMBASE (cfg,
OP_STORER4_MEMBASE_REG, ARMREG_SP, (cfg->param_area - 8), in->dreg);
creg = mono_alloc_ireg (cfg);
MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg,
OP_LOAD_MEMBASE, creg, ARMREG_SP, (cfg->param_area - 8));
@@ -1874,8 +1876,6 @@
cfg->rs->next_vreg = bb->max_vreg;
MONO_BB_FOR_EACH_INS (bb, ins) {
- MonoInst *last_ins;
-
loop_start:
switch (ins->opcode) {
case OP_ADD_IMM:
@@ -2722,17 +2722,11 @@
g_assert (imm8 >= 0);
ARM_AND_REG_IMM (code, ins->dreg, ins->sreg1, imm8,
rot_amount);
break;
-<<<<<<< .working
-=======
case OP_IDIV:
case OP_IDIV_UN:
->>>>>>> .merge-right.r95529
case OP_DIV_IMM:
-<<<<<<< .working
-=======
case OP_IREM:
case OP_IREM_UN:
->>>>>>> .merge-right.r95529
case OP_REM_IMM:
/* crappy ARM arch doesn't have a DIV instruction */
g_assert_not_reached ();
@@ -3276,8 +3270,6 @@
g_assert (arm_is_fpimm8 (ins->inst_offset));
ARM_FLDS (code, ins->dreg, ins->inst_basereg,
ins->inst_offset);
break;
-<<<<<<< .working
-=======
case OP_ICONV_TO_R_UN: {
g_assert_not_reached ();
break;
@@ -3290,7 +3282,6 @@
g_assert_not_reached ();
//ARM_FLTD (code, ins->dreg, ins->sreg1);
break;
->>>>>>> .merge-right.r95529
#endif
case OP_FCONV_TO_I1:
code = emit_float_to_int (cfg, code, ins->dreg,
ins->sreg1, 1, TRUE);
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches