1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | |
6 | /***************************************************************************/ |
7 | /* OpInfo.h */ |
8 | /***************************************************************************/ |
9 | |
10 | /* contains OpInfo, a wrapper that allows you to get useful information |
11 | about IL opcodes, and how to decode them */ |
12 | |
13 | /***************************************************************************/ |
14 | |
15 | #ifndef OpInfo_h |
16 | #define OpInfo_h |
17 | |
18 | #include "openum.h" |
19 | |
20 | // Decribes the flow of control properties of the instruction |
21 | enum OpFlow { |
22 | FLOW_META, // not a real instuction |
23 | FLOW_CALL, // a call instruction |
24 | FLOW_BRANCH, // unconditional branch, does not fall through |
25 | FLOW_COND_BRANCH, // may fall through |
26 | FLOW_PHI, |
27 | FLOW_THROW, |
28 | FLOW_BREAK, |
29 | FLOW_RETURN, |
30 | FLOW_NEXT, // flows into next instruction (none of the above) |
31 | }; |
32 | |
33 | // These are all the possible arguments for the instruction |
34 | /****************************************************************************/ |
35 | union OpArgsVal { |
36 | __int32 i; |
37 | __int64 i8; |
38 | double r; |
39 | struct { |
40 | unsigned count; |
41 | int* targets; // targets are pcrelative displacements (little-endian) |
42 | } switch_; |
43 | struct { |
44 | unsigned count; |
45 | unsigned short* vars; |
46 | } phi; |
47 | }; |
48 | |
49 | /***************************************************************************/ |
50 | |
51 | // OpInfo parses a il instrution into an opcode, and a arg and updates the IP |
52 | class OpInfo { |
53 | public: |
54 | OpInfo() { data = 0; } |
55 | OpInfo(OPCODE opCode) { _ASSERTE(opCode < CEE_COUNT); data = &table[opCode]; } |
56 | |
57 | // fetch instruction at 'instrPtr, fills in 'args' returns pointer |
58 | // to next instruction |
59 | const unsigned char* fetch(const unsigned char* instrPtr, OpArgsVal* args); |
60 | |
61 | const char* getName() { return(data->name); } |
62 | OPCODE_FORMAT getArgsInfo() { return(OPCODE_FORMAT(data->format & PrimaryMask)); } |
63 | OpFlow getFlow() { return(data->flow); } |
64 | OPCODE getOpcode() { return((OPCODE) (data-table)); } |
65 | int getNumPop() { return(data->numPop); } |
66 | int getNumPush() { return(data->numPush); } |
67 | |
68 | private: |
69 | struct OpInfoData { |
70 | const char* name; |
71 | OPCODE_FORMAT format : 8; |
72 | OpFlow flow : 8; |
73 | int numPop : 3; // < 0 means depends on instr args |
74 | int numPush : 3; // < 0 means depends on instr args |
75 | OPCODE opcode : 10; // This is the same as the index into the table |
76 | }; |
77 | |
78 | static OpInfoData table[]; |
79 | private: |
80 | OpInfoData* data; |
81 | }; |
82 | |
83 | #endif |
84 | |