-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathisa.h
159 lines (129 loc) · 4.37 KB
/
isa.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#ifndef ISA_H_HAS_BEEN_INCLUDED
#define ISA_H_HAS_BEEN_INCLUDED
#include <vector>
#include <z3++.h>
#include <string.h>
// ====================================================================================================================
// ====================================================================================================================
// ====================================================================================================================
// ====================================================================================================================
using ValueType = int32_t;
//using ValueType = uint32_t;
template <typename OperandT>
struct Operands
{
Operands(
z3::context& _ctx,
const OperandT& _x,
const OperandT& _y,
const OperandT& _imm32)
: ctx(_ctx)
, x(_x)
, y(_y)
, imm32(_imm32)
{
}
z3::context& ctx;
OperandT x;
OperandT y;
OperandT imm32;
};
using SimOperands = Operands<z3::expr>;
using EvalOperands = Operands<ValueType>;
// ====================================================================================================================
// ====================================================================================================================
#include <functional>
using FmtFn = std::function<void(const int, const int, const EvalOperands&)>;
using EvalFn = std::function<ValueType(const EvalOperands&)>;
using SimFn = std::function<z3::expr(SimOperands&)>;
struct Instruction
{
const static int Kind_None = 0;
const static int Kind_Shift = 1 << 0;
Instruction(const char* name, FmtFn fmt, SimFn sim, EvalFn eval, const int _kindMask = Kind_None)
: name_(name)
, kindMask(_kindMask)
, fmt_(fmt)
, sim_(sim)
, eval_(eval)
{
}
const char* name_ = nullptr;
int kindMask = Kind_None;
FmtFn fmt_ = nullptr;
SimFn sim_ = nullptr;
EvalFn eval_ = nullptr;
};
// ====================================================================================================================
// ====================================================================================================================
int ISA_NumOpCodes();
const char* ISA_OpName(const int opCode);
int ISA_OpCodeForName(const char* name);
void ISA_FormatOp(const int opcodeIdx, const int instrIdx, const EvalOperands& operands);
z3::expr ISA_SimulateOp(const int opcodeIdx, SimOperands& operands);
ValueType ISA_EvaluateOp(const int opcodeIdx, const EvalOperands& operands);
std::vector<int> ISA_OpCodesForKindMask(const int kindMask);
// ====================================================================================================================
// ====================================================================================================================
// Wrapper around the whole ISA to allow only selecting a subset, maps 0 -> (n-1) to the ISA[] opcodes
class ISASubset
{
public:
void addOpcode(const int opcode)
{
instOpcodes_.push_back(opcode);
}
const char* opName(const int localID)
{
return ISA_OpName(instOpcodes_[localID]);
}
int opCodeForName(const char* name)
{
for (int i = 0; i < instOpcodes_.size(); i++)
{
if (strcmp(ISA_OpName(instOpcodes_[i]), name) == 0)
{
return i;
}
}
return -1;
}
void formatOp(const int localID, const int instrIdx, const EvalOperands& operands)
{
return ISA_FormatOp(instOpcodes_[localID], instrIdx, operands);
}
z3::expr simulateOp(const int localID, SimOperands& operands)
{
return ISA_SimulateOp(instOpcodes_[localID], operands);
}
ValueType evaluateOp(const int localID, const EvalOperands& operands)
{
return ISA_EvaluateOp(instOpcodes_[localID], operands);
}
std::vector<int> opCodesForKindMask(const int kindMask)
{
std::vector<int> localIDs;
const std::vector<int> opcodes = ISA_OpCodesForKindMask(kindMask);
for (const int opcode: opcodes)
{
for (int i = 0; i < instOpcodes_.size(); i++)
{
if (opcode == instOpcodes_[i])
{
localIDs.push_back(i);
break;
}
}
}
return localIDs;
}
int size() const
{
return static_cast<int>(instOpcodes_.size());
}
private:
std::vector<int> instOpcodes_;
};
// ====================================================================================================================
// ====================================================================================================================
#endif // ISA_H_HAS_BEEN_INCLUDED