1 #pragma once
2 
3 #include <list>
4 #include <functional>
5 #include "Jitter_SymbolRef.h"
6 
7 namespace Jitter
8 {
9 	enum OPERATION
10 	{
11 		OP_NOP = 0,
12 		OP_MOV,
13 
14 		OP_ADD,
15 		OP_SUB,
16 		OP_CMP,
17 
18 		OP_AND,
19 		OP_OR,
20 		OP_XOR,
21 		OP_NOT,
22 
23 		OP_SRA,
24 		OP_SRL,
25 		OP_SLL,
26 
27 		OP_MUL,
28 		OP_MULS,
29 		OP_DIV,
30 		OP_DIVS,
31 
32 		OP_LZC,
33 
34 		OP_RELTOREF,
35 		OP_ADDREF,
36 		OP_ISREFNULL,
37 		OP_LOADFROMREF,
38 		OP_LOADFROMREFIDX,
39 		OP_LOAD8FROMREF,
40 		OP_LOAD16FROMREF,
41 		OP_STOREATREF,
42 		OP_STOREATREFIDX,
43 		OP_STORE8ATREF,
44 		OP_STORE16ATREF,
45 
46 		OP_ADD64,
47 		OP_SUB64,
48 		OP_AND64,
49 		OP_CMP64,
50 		OP_MERGETO64,
51 		OP_EXTLOW64,
52 		OP_EXTHIGH64,
53 		OP_SRA64,
54 		OP_SRL64,
55 		OP_SLL64,
56 
57 		OP_MERGETO256,
58 
59 		OP_MD_MOV_MASKED,
60 
61 		OP_MD_ADD_B,
62 		OP_MD_ADD_H,
63 		OP_MD_ADD_W,
64 
65 		OP_MD_ADDSS_B,
66 		OP_MD_ADDSS_H,
67 		OP_MD_ADDSS_W,
68 
69 		OP_MD_ADDUS_B,
70 		OP_MD_ADDUS_H,
71 		OP_MD_ADDUS_W,
72 
73 		OP_MD_SUB_B,
74 		OP_MD_SUB_H,
75 		OP_MD_SUB_W,
76 
77 		OP_MD_SUBSS_H,
78 		OP_MD_SUBSS_W,
79 
80 		OP_MD_SUBUS_B,
81 		OP_MD_SUBUS_H,
82 		OP_MD_SUBUS_W,
83 
84 		OP_MD_CMPEQ_B,
85 		OP_MD_CMPEQ_H,
86 		OP_MD_CMPEQ_W,
87 		OP_MD_CMPGT_B,
88 		OP_MD_CMPGT_H,
89 		OP_MD_CMPGT_W,
90 
91 		OP_MD_MIN_H,
92 		OP_MD_MIN_W,
93 		OP_MD_MAX_H,
94 		OP_MD_MAX_W,
95 
96 		OP_MD_AND,
97 		OP_MD_OR,
98 		OP_MD_XOR,
99 		OP_MD_NOT,
100 
101 		OP_MD_SRLH,
102 		OP_MD_SRAH,
103 		OP_MD_SLLH,
104 
105 		OP_MD_SRLW,
106 		OP_MD_SRAW,
107 		OP_MD_SLLW,
108 
109 		OP_MD_SRL256,
110 
111 		OP_MD_MAKESZ,
112 
113 		OP_MD_TOWORD_TRUNCATE,
114 		OP_MD_TOSINGLE,
115 
116 		OP_MD_EXPAND,
117 		OP_MD_UNPACK_LOWER_BH,
118 		OP_MD_UNPACK_LOWER_HW,
119 		OP_MD_UNPACK_LOWER_WD,
120 
121 		OP_MD_UNPACK_UPPER_BH,
122 		OP_MD_UNPACK_UPPER_HW,
123 		OP_MD_UNPACK_UPPER_WD,
124 
125 		OP_MD_PACK_HB,
126 		OP_MD_PACK_WH,
127 
128 		OP_MD_ADD_S,
129 		OP_MD_SUB_S,
130 		OP_MD_MUL_S,
131 		OP_MD_DIV_S,
132 		OP_MD_ABS_S,
133 		OP_MD_MIN_S,
134 		OP_MD_MAX_S,
135 
136 		OP_MD_CMPLT_S,
137 		OP_MD_CMPGT_S,
138 
139 		OP_FP_ADD,
140 		OP_FP_SUB,
141 		OP_FP_MUL,
142 		OP_FP_DIV,
143 		OP_FP_SQRT,
144 		OP_FP_RSQRT,
145 		OP_FP_RCPL,
146 		OP_FP_ABS,
147 		OP_FP_NEG,
148 		OP_FP_MAX,
149 		OP_FP_MIN,
150 		OP_FP_CMP,
151 
152 		OP_FP_LDCST,
153 		OP_FP_TOINT_TRUNC,
154 
155 		OP_PARAM,
156 		OP_PARAM_RET,
157 		OP_CALL,
158 		OP_RETVAL,
159 		OP_JMP,
160 		OP_CONDJMP,
161 		OP_EXTERNJMP,     //Pass control to another function with same signature (void (*)(void*)) and same input parameter
162 		OP_EXTERNJMP_DYN, //Same as above, but destination can be changed at run time, cannot be used in AOT mode
163 		OP_GOTO,
164 		OP_BREAK,
165 
166 		OP_LABEL,
167 	};
168 
169 	enum CONDITION
170 	{
171 		CONDITION_NEVER = 0,
172 		CONDITION_EQ,
173 		CONDITION_NE,
174 		CONDITION_BL,
175 		CONDITION_BE,
176 		CONDITION_AB,
177 		CONDITION_AE,
178 		CONDITION_LT,
179 		CONDITION_LE,
180 		CONDITION_GT,
181 		CONDITION_GE,
182 	};
183 
184 	struct STATEMENT
185 	{
186 	public:
STATEMENTSTATEMENT187 		STATEMENT()
188 			: op(OP_NOP)
189 			, jmpBlock(-1)
190 			, jmpCondition(CONDITION_NEVER)
191 		{
192 
193 		}
194 
195 		OPERATION		op;
196 		SymbolRefPtr	src1;
197 		SymbolRefPtr	src2;
198 		SymbolRefPtr	src3;
199 		SymbolRefPtr	dst;
200 		uint32			jmpBlock;
201 		CONDITION		jmpCondition;
202 
203 		typedef std::function<void (SymbolRefPtr&, bool)> OperandVisitor;
204 		typedef std::function<void (const SymbolRefPtr&, bool)> ConstOperandVisitor;
205 
VisitOperandsSTATEMENT206 		void VisitOperands(const OperandVisitor& visitor)
207 		{
208 			if(dst) visitor(dst, true);
209 			if(src1) visitor(src1, false);
210 			if(src2) visitor(src2, false);
211 			if(src3) visitor(src3, false);
212 		}
213 
VisitOperandsSTATEMENT214 		void VisitOperands(const ConstOperandVisitor& visitor) const
215 		{
216 			if(dst) visitor(dst, true);
217 			if(src1) visitor(src1, false);
218 			if(src2) visitor(src2, false);
219 			if(src3) visitor(src3, false);
220 		}
221 
VisitDestinationSTATEMENT222 		void VisitDestination(const ConstOperandVisitor& visitor) const
223 		{
224 			if(dst) visitor(dst, true);
225 		}
226 
VisitSourcesSTATEMENT227 		void VisitSources(const OperandVisitor& visitor)
228 		{
229 			if(src1) visitor(src1, false);
230 			if(src2) visitor(src2, false);
231 			if(src3) visitor(src3, false);
232 		}
233 
VisitSourcesSTATEMENT234 		void VisitSources(const ConstOperandVisitor& visitor) const
235 		{
236 			if(src1) visitor(src1, false);
237 			if(src2) visitor(src2, false);
238 			if(src3) visitor(src3, false);
239 		}
240 	};
241 
242 	typedef std::list<STATEMENT> StatementList;
243 
244 	std::string		ConditionToString(CONDITION);
245 	void			DumpStatementList(const StatementList&);
246 	void			DumpStatementList(std::ostream&, const StatementList&);
247 
248 	template<typename ListType, typename IteratorType, typename ValueType>
249 	class IndexedStatementListBase
250 	{
251 	public:
252 		struct ITERATOR
253 		{
254 		public:
255 			struct VALUE
256 			{
VALUEITERATOR::VALUE257 				VALUE(const IteratorType& iterator, ValueType& statement, unsigned int index)
258 					: iterator(iterator), statement(statement), index(index)
259 				{
260 
261 				}
262 
263 				IteratorType iterator;
264 				ValueType& statement;
265 				unsigned int index = 0;
266 			};
267 
ITERATORITERATOR268 			ITERATOR(const IteratorType& iterator, unsigned int index)
269 				: m_iterator(iterator)
270 				, m_index(index)
271 			{
272 
273 			}
274 
275 			const ITERATOR& operator ++()
276 			{
277 				assert(m_index != -1);
278 				m_iterator++;
279 				m_index++;
280 				return (*this);
281 			}
282 
283 			bool operator !=(const ITERATOR& rhs) const
284 			{
285 				return m_iterator != rhs.m_iterator;
286 			}
287 
288 			VALUE operator *() const
289 			{
290 				return VALUE(m_iterator, *m_iterator, m_index);
291 			}
292 
293 		private:
294 			IteratorType m_iterator;
295 			unsigned int m_index = 0;
296 		};
297 
IndexedStatementListBase(ListType & statements)298 		IndexedStatementListBase(ListType& statements)
299 			: m_statements(statements) { }
300 
begin()301 		ITERATOR begin() const
302 		{
303 			return ITERATOR(m_statements.begin(), 0);
304 		}
305 
end()306 		ITERATOR end() const
307 		{
308 			return ITERATOR(m_statements.end(), -1);
309 		}
310 
311 	private:
312 		ListType& m_statements;
313 	};
314 
315 	typedef IndexedStatementListBase<StatementList, StatementList::iterator, STATEMENT> IndexedStatementList;
316 	typedef IndexedStatementListBase<const StatementList, StatementList::const_iterator, const STATEMENT> ConstIndexedStatementList;
317 }
318