New test.
[mono.git] / mono / metadata / opcodes.c
1 /*
2  * opcodes.c: CIL instruction information
3  *
4  * Author:
5  *   Paolo Molaro (lupus@ximian.com)
6  *
7  * (C) 2002 Ximian, Inc.
8  */
9 #include <mono/metadata/opcodes.h>
10 #include <stddef.h> /* for NULL */
11 #include <config.h>
12
13 #define MONO_PREFIX1_OFFSET MONO_CEE_ARGLIST
14 #define MONO_CUSTOM_PREFIX_OFFSET MONO_CEE_MONO_ICALL
15
16 #define OPDEF(a,b,c,d,e,f,g,h,i,j) \
17         { Mono ## e, MONO_FLOW_ ## j, MONO_ ## a },
18
19 const MonoOpcode
20 mono_opcodes [MONO_CEE_LAST + 1] = {
21 #include "mono/cil/opcode.def"
22         {0}
23 };
24
25 #undef OPDEF
26
27 #ifdef HAVE_ARRAY_ELEM_INIT
28 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
29 #define MSGSTRFIELD1(line) str##line
30 static const struct msgstr_t {
31 #define OPDEF(a,b,c,d,e,f,g,h,i,j) char MSGSTRFIELD(__LINE__) [sizeof (b)];
32 #include "mono/cil/opcode.def"
33 #undef OPDEF
34 } opstr = {
35 #define OPDEF(a,b,c,d,e,f,g,h,i,j) b,
36 #include "mono/cil/opcode.def"
37 #undef OPDEF
38 };
39 static const gint16 opidx [] = {
40 #define OPDEF(a,b,c,d,e,f,g,h,i,j) [MONO_ ## a] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
41 #include "mono/cil/opcode.def"
42 #undef OPDEF
43 };
44
45 const char*
46 mono_opcode_name (int opcode)
47 {
48         return (const char*)&opstr + opidx [opcode];
49 }
50
51 #else
52 #define OPDEF(a,b,c,d,e,f,g,h,i,j) b,
53 static const char* const
54 mono_opcode_names [MONO_CEE_LAST + 1] = {
55 #include "mono/cil/opcode.def"
56         NULL
57 };
58
59 const char*
60 mono_opcode_name (int opcode)
61 {
62         return mono_opcode_names [opcode];
63 }
64
65 #endif
66
67 MonoOpcodeEnum
68 mono_opcode_value (const guint8 **ip, const guint8 *end)
69 {
70         MonoOpcodeEnum res;
71         const guint8 *p = *ip;
72
73         if (p >= end)
74                 return -1;
75         if (*p == 0xfe) {
76                 ++p;
77                 if (p >= end)
78                         return -1;
79                 res = *p + MONO_PREFIX1_OFFSET;
80         } else if (*p == MONO_CUSTOM_PREFIX) {
81                 ++p;
82                 if (p >= end)
83                         return -1;
84                 res = *p + MONO_CUSTOM_PREFIX_OFFSET;
85         } else {
86                 res = *p;
87         }
88         *ip = p;
89         return res;
90 }
91