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
21enum 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/****************************************************************************/
35union 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
52class OpInfo {
53public:
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
68private:
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[];
79private:
80 OpInfoData* data;
81};
82
83#endif
84