Author: zoltan
Date: 2008-02-07 14:40:50 -0500 (Thu, 07 Feb 2008)
New Revision: 95183
Modified:
trunk/mono/mono/mini/cpu-arm.md
trunk/mono/mono/mini/mini-arm.c
trunk/mono/mono/mini/mini-arm.h
trunk/mono/mono/mini/mini.c
Log:
2008-02-07 Zoltan Varga <[EMAIL PROTECTED]>
* mini.c (mono_normalize_opcodes): Add some more opcodes.
* mini-arm.c mini-arm.h cpu-arm.md: Get rid of CEE_ opcodes.
Modified: trunk/mono/mono/mini/cpu-arm.md
===================================================================
--- trunk/mono/mono/mini/cpu-arm.md 2008-02-07 19:27:10 UTC (rev 95182)
+++ trunk/mono/mono/mini/cpu-arm.md 2008-02-07 19:40:50 UTC (rev 95183)
@@ -1,4 +1,4 @@
-# powerpc cpu description file
+# arm cpu description file
# this file is read by genmdesc to pruduce a table with all the relevant
information
# about the cpu instructions that may be used by the regsiter allocator, the
scheduler
# and other parts of the arch-dependent part of mini.
@@ -50,61 +50,17 @@
nop: len:4
break: len:4
jmp: len:92
-call: dest:a clob:c len:20
br: len:4
-beq: len:8
-bge: len:8
-bgt: len:8
-ble: len:8
-blt: len:8
-bne.un: len:8
-bge.un: len:8
-bgt.un: len:8
-ble.un: len:8
-blt.un: len:8
switch: src1:i len:8
-add: dest:i src1:i src2:i len:4
-sub: dest:i src1:i src2:i len:4
-mul: dest:i src1:i src2:i len:4
-div: dest:i src1:i src2:i len:40
-div.un: dest:i src1:i src2:i len:16
-rem: dest:i src1:i src2:i len:48
-rem.un: dest:i src1:i src2:i len:24
-and: dest:i src1:i src2:i len:4
-or: dest:i src1:i src2:i len:4
-xor: dest:i src1:i src2:i len:4
-shl: dest:i src1:i src2:i len:4
-shr: dest:i src1:i src2:i len:4
-shr.un: dest:i src1:i src2:i len:4
-neg: dest:i src1:i len:4
-not: dest:i src1:i len:4
-conv.i1: dest:i src1:i len:8
-conv.i2: dest:i src1:i len:8
-conv.i4: dest:i src1:i len:4
-conv.r4: dest:f src1:i len:36
-conv.r8: dest:f src1:i len:36
-conv.u4: dest:i src1:i
-conv.r.un: dest:f src1:i len:56
+
throw: src1:i len:24
rethrow: src1:i len:20
-ckfinite: dest:f src1:f len:24
-conv.u2: dest:i src1:i len:8
-conv.u1: dest:i src1:i len:4
-conv.i: dest:i src1:i len:4
-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
start_handler: len:20
endfinally: len:20
-conv.u: dest:i src1:i len:4
+call_handler: len:12
+endfilter: src1:i len:16
+
+ckfinite: dest:f src1:f len:24
ceq: dest:i len:12
cgt: dest:i len:12
cgt.un: dest:i len:12
@@ -120,6 +76,9 @@
setret: dest:a src1:i len:4
setlret: src1:i src2:i len:12
checkthis: src1:b len:4
+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
voidcall: len:20 clob:c
voidcall_reg: src1:i len:8 clob:c
voidcall_membase: src1:b len:12 clob:c
@@ -132,8 +91,6 @@
vcall: len:20 clob:c
vcall_reg: src1:i len:8 clob:c
vcall_membase: src1:b len:12 clob:c
-call_reg: dest:a src1:i len:8 clob:c
-call_membase: dest:a src1:b len:12 clob:c
iconst: dest:i len:16
r4const: dest:f len:20
r8const: dest:f len:20
@@ -177,9 +134,6 @@
add_imm: dest:i src1:i len:12
sub_imm: dest:i src1:i len:12
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)
div_imm: dest:i src1:i src2:i len:20
div_un_imm: dest:i src1:i src2:i len:12
rem_imm: dest:i src1:i src2:i len:28
@@ -204,9 +158,6 @@
cond_exc_no: len:8
cond_exc_c: len:12
cond_exc_nc: len:8
-long_conv_to_ovf_i: dest:i src1:i src2:i len:30
-long_mul_ovf:
-long_conv_to_r_un: dest:f src1:i src2:i len:37
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
@@ -242,8 +193,6 @@
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
-call_handler: len:12
-endfilter: src1:i len:16
aot_const: dest:i len:16
sqrt: dest:f src1:f len:4
adc: dest:i src1:i src2:i len:4
@@ -255,8 +204,57 @@
sbb: dest:i src1:i src2:i len:4
sbb_imm: dest:i src1:i len:12
br_reg: src1:i len:8
-arm_rsbs_imm: dest:i src1:i len:4
-arm_rsc_imm: dest:i src1:i len:4
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
+
+# 32 bit opcodes
+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
+conv.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_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
+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
+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
+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
+
+long_conv_to_ovf_i: dest:i src1:i src2:i len:30
+
+arm_rsbs_imm: dest:i src1:i len:4
+arm_rsc_imm: dest:i src1:i len:4
Modified: trunk/mono/mono/mini/mini-arm.c
===================================================================
--- trunk/mono/mono/mini/mini-arm.c 2008-02-07 19:27:10 UTC (rev 95182)
+++ trunk/mono/mono/mini/mini-arm.c 2008-02-07 19:40:50 UTC (rev 95183)
@@ -1376,7 +1376,7 @@
if (last_ins && (last_ins->opcode ==
OP_STOREI1_MEMBASE_REG) &&
ins->inst_basereg ==
last_ins->inst_destbasereg &&
ins->inst_offset ==
last_ins->inst_offset) {
- ins->opcode = (ins->opcode ==
OP_LOADI1_MEMBASE) ? CEE_CONV_I1 : CEE_CONV_U1;
+ ins->opcode = (ins->opcode ==
OP_LOADI1_MEMBASE) ? OP_ICONV_TO_I1 : OP_ICONV_TO_U1;
ins->sreg1 = last_ins->sreg1;
}
break;
@@ -1385,12 +1385,10 @@
if (last_ins && (last_ins->opcode ==
OP_STOREI2_MEMBASE_REG) &&
ins->inst_basereg ==
last_ins->inst_destbasereg &&
ins->inst_offset ==
last_ins->inst_offset) {
- ins->opcode = (ins->opcode ==
OP_LOADI2_MEMBASE) ? CEE_CONV_I2 : CEE_CONV_U2;
+ ins->opcode = (ins->opcode ==
OP_LOADI2_MEMBASE) ? OP_ICONV_TO_I2 : OP_ICONV_TO_U2;
ins->sreg1 = last_ins->sreg1;
}
break;
- case CEE_CONV_I4:
- case CEE_CONV_U4:
case OP_MOVE:
ins->opcode = OP_MOVE;
/*
@@ -1456,11 +1454,11 @@
{
switch (op) {
case OP_ADD_IMM:
- return CEE_ADD;
+ return OP_IADD;
case OP_SUB_IMM:
- return CEE_SUB;
+ return OP_ISUB;
case OP_AND_IMM:
- return CEE_AND;
+ return OP_IAND;
case OP_COMPARE_IMM:
return OP_COMPARE;
case OP_ADDCC_IMM:
@@ -1472,9 +1470,9 @@
case OP_SBB_IMM:
return OP_SBB;
case OP_OR_IMM:
- return CEE_OR;
+ return OP_IOR;
case OP_XOR_IMM:
- return CEE_XOR;
+ return OP_IXOR;
case OP_LOAD_MEMBASE:
return OP_LOAD_MEMINDEX;
case OP_LOADI4_MEMBASE:
@@ -1572,7 +1570,7 @@
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_regstate_next_int (cfg->rs);
ins->sreg2 = temp->dreg;
- ins->opcode = CEE_MUL;
+ ins->opcode = OP_IMUL;
break;
case OP_LOAD_MEMBASE:
case OP_LOADI4_MEMBASE:
@@ -2167,18 +2165,18 @@
g_assert (arm_is_imm8 (ins->inst_offset));
ARM_LDRSH_IMM (code, ins->dreg, ins->inst_basereg,
ins->inst_offset);
break;
- case CEE_CONV_I1:
+ case OP_ICONV_TO_I1:
ARM_SHL_IMM (code, ins->dreg, ins->sreg1, 24);
ARM_SAR_IMM (code, ins->dreg, ins->dreg, 24);
break;
- case CEE_CONV_I2:
+ case OP_ICONV_TO_I2:
ARM_SHL_IMM (code, ins->dreg, ins->sreg1, 16);
ARM_SAR_IMM (code, ins->dreg, ins->dreg, 16);
break;
- case CEE_CONV_U1:
+ case OP_ICONV_TO_U1:
ARM_AND_REG_IMM8 (code, ins->dreg, ins->sreg1, 0xff);
break;
- case CEE_CONV_U2:
+ case OP_ICONV_TO_U2:
ARM_SHL_IMM (code, ins->dreg, ins->sreg1, 16);
ARM_SHR_IMM (code, ins->dreg, ins->dreg, 16);
break;
@@ -2199,7 +2197,7 @@
case OP_ADDCC:
ARM_ADDS_REG_REG (code, ins->dreg, ins->sreg1,
ins->sreg2);
break;
- case CEE_ADD:
+ case OP_IADD:
ARM_ADD_REG_REG (code, ins->dreg, ins->sreg1,
ins->sreg2);
break;
case OP_ADC:
@@ -2220,19 +2218,19 @@
g_assert (imm8 >= 0);
ARM_ADCS_REG_IMM (code, ins->dreg, ins->sreg1, imm8,
rot_amount);
break;
- case CEE_ADD_OVF:
+ case OP_IADD_OVF:
ARM_ADD_REG_REG (code, ins->dreg, ins->sreg1,
ins->sreg2);
//EMIT_COND_SYSTEM_EXCEPTION_FLAGS (PPC_BR_FALSE,
PPC_BR_EQ, "OverflowException");
break;
- case CEE_ADD_OVF_UN:
+ case OP_IADD_OVF_UN:
ARM_ADD_REG_REG (code, ins->dreg, ins->sreg1,
ins->sreg2);
//EMIT_COND_SYSTEM_EXCEPTION_FLAGS (PPC_BR_FALSE,
PPC_BR_EQ, "OverflowException");
break;
- case CEE_SUB_OVF:
+ case OP_ISUB_OVF:
ARM_SUB_REG_REG (code, ins->dreg, ins->sreg1,
ins->sreg2);
//EMIT_COND_SYSTEM_EXCEPTION_FLAGS (PPC_BR_FALSE,
PPC_BR_EQ, "OverflowException");
break;
- case CEE_SUB_OVF_UN:
+ case OP_ISUB_OVF_UN:
ARM_SUB_REG_REG (code, ins->dreg, ins->sreg1,
ins->sreg2);
//EMIT_COND_SYSTEM_EXCEPTION_FLAGS (PPC_BR_TRUE,
PPC_BR_EQ, "OverflowException");
break;
@@ -2260,7 +2258,7 @@
g_assert (imm8 >= 0);
ARM_SUBS_REG_IMM (code, ins->dreg, ins->sreg1, imm8,
rot_amount);
break;
- case CEE_SUB:
+ case OP_ISUB:
ARM_SUB_REG_REG (code, ins->dreg, ins->sreg1,
ins->sreg2);
break;
case OP_SBB:
@@ -2286,7 +2284,7 @@
g_assert (imm8 >= 0);
ARM_RSC_REG_IMM (code, ins->dreg, ins->sreg1, imm8,
rot_amount);
break;
- case CEE_AND:
+ case OP_IAND:
ARM_AND_REG_REG (code, ins->dreg, ins->sreg1,
ins->sreg2);
break;
case OP_AND_IMM:
@@ -2294,15 +2292,15 @@
g_assert (imm8 >= 0);
ARM_AND_REG_IMM (code, ins->dreg, ins->sreg1, imm8,
rot_amount);
break;
- case CEE_DIV:
- case CEE_DIV_UN:
+ case OP_IDIV:
+ case OP_IDIV_UN:
case OP_DIV_IMM:
- case CEE_REM:
- case CEE_REM_UN:
+ case OP_IREM:
+ case OP_IREM_UN:
case OP_REM_IMM:
/* crappy ARM arch doesn't have a DIV instruction */
g_assert_not_reached ();
- case CEE_OR:
+ case OP_IOR:
ARM_ORR_REG_REG (code, ins->dreg, ins->sreg1,
ins->sreg2);
break;
case OP_OR_IMM:
@@ -2310,7 +2308,7 @@
g_assert (imm8 >= 0);
ARM_ORR_REG_IMM (code, ins->dreg, ins->sreg1, imm8,
rot_amount);
break;
- case CEE_XOR:
+ case OP_IXOR:
ARM_EOR_REG_REG (code, ins->dreg, ins->sreg1,
ins->sreg2);
break;
case OP_XOR_IMM:
@@ -2318,14 +2316,14 @@
g_assert (imm8 >= 0);
ARM_EOR_REG_IMM (code, ins->dreg, ins->sreg1, imm8,
rot_amount);
break;
- case CEE_SHL:
+ case OP_ISHL:
ARM_SHL_REG (code, ins->dreg, ins->sreg1, ins->sreg2);
break;
case OP_SHL_IMM:
if (ins->inst_imm)
ARM_SHL_IMM (code, ins->dreg, ins->sreg1,
(ins->inst_imm & 0x1f));
break;
- case CEE_SHR:
+ case OP_ISHR:
ARM_SAR_REG (code, ins->dreg, ins->sreg1, ins->sreg2);
break;
case OP_SHR_IMM:
@@ -2336,16 +2334,16 @@
if (ins->inst_imm)
ARM_SHR_IMM (code, ins->dreg, ins->sreg1,
(ins->inst_imm & 0x1f));
break;
- case CEE_SHR_UN:
+ case OP_ISHR_UN:
ARM_SHR_REG (code, ins->dreg, ins->sreg1, ins->sreg2);
break;
- case CEE_NOT:
+ case OP_INOT:
ARM_MVN_REG_REG (code, ins->dreg, ins->sreg1);
break;
- case CEE_NEG:
+ case OP_INEG:
ARM_RSB_REG_IMM8 (code, ins->dreg, ins->sreg1, 0);
break;
- case CEE_MUL:
+ case OP_IMUL:
if (ins->dreg == ins->sreg2)
ARM_MUL_REG_REG (code, ins->dreg, ins->sreg1,
ins->sreg2);
else
@@ -2354,11 +2352,11 @@
case OP_MUL_IMM:
g_assert_not_reached ();
break;
- case CEE_MUL_OVF:
+ case OP_IMUL_OVF:
/* FIXME: handle ovf/ sreg2 != dreg */
ARM_MUL_REG_REG (code, ins->dreg, ins->sreg1,
ins->sreg2);
break;
- case CEE_MUL_OVF_UN:
+ case OP_IMUL_OVF_UN:
/* FIXME: handle ovf/ sreg2 != dreg */
ARM_MUL_REG_REG (code, ins->dreg, ins->sreg1,
ins->sreg2);
break;
@@ -2375,8 +2373,8 @@
/* Load the value from the GOT */
ARM_LDR_REG_REG (code, ins->dreg, ARMREG_PC, ins->dreg);
break;
- case CEE_CONV_I4:
- case CEE_CONV_U4:
+ case OP_ICONV_TO_I4:
+ case OP_ICONV_TO_U4:
case OP_MOVE:
if (ins->dreg != ins->sreg1)
ARM_MOV_REG_REG (code, ins->dreg, ins->sreg1);
@@ -2640,17 +2638,17 @@
case OP_COND_EXC_NO:
g_assert_not_reached ();
break;
- case CEE_BEQ:
- case CEE_BNE_UN:
- case CEE_BLT:
- case CEE_BLT_UN:
- case CEE_BGT:
- case CEE_BGT_UN:
- case CEE_BGE:
- case CEE_BGE_UN:
- case CEE_BLE:
- case CEE_BLE_UN:
- EMIT_COND_BRANCH (ins, ins->opcode - CEE_BEQ);
+ case OP_IBEQ:
+ case OP_IBNE_UN:
+ case OP_IBLT:
+ case OP_IBLT_UN:
+ case OP_IBGT:
+ case OP_IBGT_UN:
+ case OP_IBGE:
+ case OP_IBGE_UN:
+ case OP_IBLE:
+ case OP_IBLE_UN:
+ EMIT_COND_BRANCH (ins, ins->opcode - OP_IBEQ);
break;
/* floating point opcodes */
@@ -2724,10 +2722,10 @@
*/
break;
}
- case CEE_CONV_R4:
+ case OP_ICONV_TO_R4:
ARM_FLTS (code, ins->dreg, ins->sreg1);
break;
- case CEE_CONV_R8:
+ case OP_ICONV_TO_R8:
ARM_FLTD (code, ins->dreg, ins->sreg1);
break;
#elif defined(ARM_FPU_VFP)
@@ -2776,15 +2774,15 @@
g_assert (arm_is_fpimm8 (ins->inst_offset));
ARM_FLDS (code, ins->dreg, ins->inst_basereg,
ins->inst_offset);
break;
- case CEE_CONV_R_UN: {
+ case OP_ICONV_TO_R_UN: {
g_assert_not_reached ();
break;
}
- case CEE_CONV_R4:
+ case OP_ICONV_TO_R4:
g_assert_not_reached ();
//ARM_FLTS (code, ins->dreg, ins->sreg1);
break;
- case CEE_CONV_R8:
+ case OP_ICONV_TO_R8:
g_assert_not_reached ();
//ARM_FLTD (code, ins->dreg, ins->sreg1);
break;
@@ -2950,7 +2948,7 @@
#elif defined(ARM_FPU_VFP)
ARM_CMPD (code, ins->sreg1, ins->sreg2);
#endif
- EMIT_COND_BRANCH (ins, CEE_BEQ - CEE_BEQ);
+ EMIT_COND_BRANCH (ins, OP_IBEQ - OP_IBEQ);
break;
case OP_FBNE_UN:
#ifdef ARM_FPU_FPA
@@ -2958,7 +2956,7 @@
#elif defined(ARM_FPU_VFP)
ARM_CMPD (code, ins->sreg1, ins->sreg2);
#endif
- EMIT_COND_BRANCH (ins, CEE_BNE_UN - CEE_BEQ);
+ EMIT_COND_BRANCH (ins, OP_IBNE_UN - OP_IBEQ);
break;
case OP_FBLT:
#ifdef ARM_FPU_FPA
@@ -3034,7 +3032,7 @@
ppc_rlwinm (code, ppc_r11, ppc_r11, 0, 1, 31);
ppc_addis (code, ppc_r11, ppc_r11, -32752);
ppc_rlwinmd (code, ppc_r11, ppc_r11, 1, 31, 31);
- EMIT_COND_SYSTEM_EXCEPTION (CEE_BEQ - CEE_BEQ,
"ArithmeticException");*/
+ EMIT_COND_SYSTEM_EXCEPTION (OP_IBEQ - OP_IBEQ,
"ArithmeticException");*/
g_assert_not_reached ();
break;
}
Modified: trunk/mono/mono/mini/mini-arm.h
===================================================================
--- trunk/mono/mono/mini/mini-arm.h 2008-02-07 19:27:10 UTC (rev 95182)
+++ trunk/mono/mono/mini/mini-arm.h 2008-02-07 19:40:50 UTC (rev 95183)
@@ -114,6 +114,8 @@
#define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE
#define MONO_ARCH_COMMON_VTABLE_TRAMPOLINE 1
+#define MONO_ARCH_ENABLE_NORMALIZE_OPCODES 1
+
#define ARM_NUM_REG_ARGS (ARM_LAST_ARG_REG-ARM_FIRST_ARG_REG+1)
#define ARM_NUM_REG_FPARGS 0
Modified: trunk/mono/mono/mini/mini.c
===================================================================
--- trunk/mono/mono/mini/mini.c 2008-02-07 19:27:10 UTC (rev 95182)
+++ trunk/mono/mono/mini/mini.c 2008-02-07 19:40:50 UTC (rev 95183)
@@ -10933,6 +10933,10 @@
remap_table [CEE_BGE_UN] = REMAP_OPCODE (BGE_UN);
remap_table [CEE_BLE] = REMAP_OPCODE (BLE);
remap_table [CEE_BLE_UN] = REMAP_OPCODE (BLE_UN);
+ remap_table [CEE_ADD_OVF] = REMAP_OPCODE (ADD_OVF);
+ remap_table [CEE_ADD_OVF_UN] = REMAP_OPCODE (ADD_OVF_UN);
+ remap_table [CEE_SUB_OVF] = REMAP_OPCODE (SUB_OVF);
+ remap_table [CEE_SUB_OVF_UN] = REMAP_OPCODE (SUB_OVF_UN);
remap_table [CEE_MUL_OVF] = REMAP_OPCODE (MUL_OVF);
remap_table [CEE_MUL_OVF_UN] = REMAP_OPCODE (MUL_OVF_UN);
}
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches