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