[generics.cs] enable more testcases for interpreter
[mono.git] / mono / mini / interpreter / mintops.c
1 /*
2  * Utilities for handling interpreter VM instructions
3  *
4  * Authors:
5  *   Bernie Solomon (bernard@ugsolutions.com)
6  *
7  */
8 #include <glib.h>
9 #include <stdio.h>
10 #include "mintops.h"
11
12 #define OPDEF(a,b,c,d) \
13         b,
14 const char *mono_interp_opname[] = {
15 #include "mintops.def"
16         ""
17 };
18 #undef OPDEF
19
20 #define OPDEF(a,b,c,d) \
21         c,
22 unsigned char mono_interp_oplen[] = {
23 #include "mintops.def"
24         0
25 };
26 #undef OPDEF
27
28
29 #define OPDEF(a,b,c,d) \
30         d,
31 MintOpArgType mono_interp_opargtype[] = {
32 #include "mintops.def"
33         0
34 };
35 #undef OPDEF
36
37 const guint16 *
38 mono_interp_dis_mintop(const guint16 *base, const guint16 *ip)
39 {
40         int len = mono_interp_oplen [*ip];
41         guint32 token;
42         int target;
43         if (len < 0 || len > 10) {
44                 g_print ("op %d len %d\n", *ip, len);
45                 g_assert_not_reached ();
46         } else if (len == 0) { /* SWITCH */
47                 int n = READ32 (ip + 1);
48                 len = 3 + n * 2;
49         }
50
51         g_print ("IL_%04x: %-10s", ip - base, mono_interp_opname [*ip]);
52         switch (mono_interp_opargtype [*ip]) {
53         case MintOpNoArgs:
54                 break;
55         case MintOpUShortInt:
56                 g_print (" %u", * (guint16 *)(ip + 1));
57                 break;
58         case MintOpTwoShorts:
59                 g_print (" %u,%u", * (guint16 *)(ip + 1), * (guint16 *)(ip + 2));
60                 break;
61         case MintOpShortAndInt:
62                 g_print (" %u,%u", * (guint16 *)(ip + 1), (guint32)READ32(ip + 2));
63                 break;
64         case MintOpShortInt:
65                 g_print (" %d", * (short *)(ip + 1));
66                 break;
67         case MintOpClassToken:
68         case MintOpMethodToken:
69         case MintOpFieldToken:
70                 token = * (guint16 *)(ip + 1);
71                 g_print (" %u", token);
72                 break;
73         case MintOpInt:
74                 g_print (" %d", (gint32)READ32 (ip + 1));
75                 break;
76         case MintOpLongInt:
77                 g_print (" %lld", (gint64)READ64 (ip + 1));
78                 break;
79         case MintOpFloat: {
80                 gint32 tmp = READ32 (ip + 1);
81                 g_print (" %g", * (float *)&tmp);
82                 break;
83         }
84         case MintOpDouble: {
85                 gint64 tmp = READ64 (ip + 1);
86                 g_print (" %g", * (double *)&tmp);
87                 break;
88         }
89         case MintOpShortBranch:
90                 target = ip + * (short *)(ip + 1) - base;
91                 g_print (" IL_%04x", target);
92                 break;
93         case MintOpBranch:
94                 target = ip + (gint32)READ32 (ip + 1) - base;
95                 g_print (" IL_%04x", target);
96                 break;
97         case MintOpSwitch: {
98                 const guint16 *p = ip + 1;
99                 int sval = (gint32)READ32 (p);
100                 int i;
101                 p += 2;
102                 g_print ("(");
103                 for (i = 0; i < sval; ++i) {
104                         int offset;
105                         if (i > 0)
106                                 g_print (", ");
107                         offset = (gint32)READ32 (p);
108                         g_print ("IL_%04x", ip - base + 3 + 2 * sval + offset);
109                         p += 2;
110                 }
111                 g_print (")");
112                 break;
113         }
114         default:
115                 g_print("unknown arg type\n");
116         }
117
118         return ip + len;
119 }
120