1 /*========================== begin_copyright_notice ============================ 2 3 Copyright (C) 2017-2021 Intel Corporation 4 5 SPDX-License-Identifier: MIT 6 7 ============================= end_copyright_notice ===========================*/ 8 9 #ifndef _IGA_BACKEND_GED_DECODER_HPP_ 10 #define _IGA_BACKEND_GED_DECODER_HPP_ 11 12 #include "GEDBitProcessor.hpp" 13 #include "GEDToIGATranslation.hpp" 14 #include "ged.h" 15 16 17 #define GED_DECODE_TO(FIELD, TRANS, DST) \ 18 do { \ 19 GED_RETURN_VALUE _status; \ 20 DST = TRANS(GED_Get ## FIELD(&m_currGedInst, &_status)); \ 21 if (_status != GED_RETURN_VALUE_SUCCESS) { \ 22 handleGedDecoderError(__LINE__, #FIELD, _status); \ 23 } \ 24 } while (0) 25 26 #define GED_DECODE_RAW_TO(FIELD, DST) \ 27 do { \ 28 GED_RETURN_VALUE _status; \ 29 DST = GED_Get ## FIELD(&m_currGedInst, &_status); \ 30 if (_status != GED_RETURN_VALUE_SUCCESS) { \ 31 handleGedDecoderError(__LINE__, #FIELD, _status); \ 32 } \ 33 } while (0) 34 35 #define GED_DECODE_RAW(GED_TYPE, ID, FIELD) \ 36 GED_TYPE ID; \ 37 GED_DECODE_RAW_TO(FIELD, ID); 38 39 #define GED_DECODE(IGA_TYPE, GED_TYPE, ID, FIELD) \ 40 GED_DECODE_RAW(GED_TYPE, GED_ ## ID, FIELD); \ 41 IGA_TYPE ID = translate(GED_ ## ID); 42 43 #define GED_DECODE_RAW_TO_SRC(DST, TYPE, FIELD) \ 44 do { \ 45 GED_RETURN_VALUE _STATUS; \ 46 DST = GED_Get ## FIELD(&m_currGedInst, &_STATUS); \ 47 if (_STATUS != GED_RETURN_VALUE_SUCCESS) { \ 48 handleGedDecoderError(__LINE__, #FIELD, _STATUS); \ 49 } \ 50 } while (0) 51 52 #define RETURN_GED_DECODE_RAW_TO_SRC(TYPE, FIELD) { \ 53 TYPE _DST; \ 54 GED_DECODE_RAW_TO_SRC(_DST, TYPE, FIELD); \ 55 return _DST; \ 56 } 57 // the extra namespace declaration is needed to make g++ happy 58 #define DEFINE_SOURCE_ACCESSOR(TYPE, FIELD, I) \ 59 namespace iga { \ 60 template <> TYPE Decoder::decodeSrc ## FIELD <SourceIndex::SRC##I>() { \ 61 RETURN_GED_DECODE_RAW_TO_SRC(TYPE, Src ## I ## FIELD); \ 62 } \ 63 } 64 65 /* #define DEFINE_SOURCE_ACCESSOR_INLINE(TYPE, FIELD, I) \ 66 template <> TYPE decodeSrc ## FIELD <SourceIndex::SRC##I>() { \ 67 RETURN_GED_DECODE_RAW_TO_SRC(TYPE, Src ## I ## FIELD); \ 68 } 69 */ 70 /* #define DEFINE_GED_SOURCE_ACCESSORS_INLINE_01(TYPE, FIELD) \ 71 DEFINE_SOURCE_ACCESSOR_INLINE(TYPE, FIELD, 0) \ 72 DEFINE_SOURCE_ACCESSOR_INLINE(TYPE, FIELD, 1) 73 */ 74 #define DEFINE_GED_SOURCE_ACCESSORS_01(TYPE, FIELD) \ 75 DEFINE_SOURCE_ACCESSOR(TYPE, FIELD, 0) \ 76 DEFINE_SOURCE_ACCESSOR(TYPE, FIELD, 1) 77 78 /* #define DEFINE_GED_SOURCE_ACCESSORS_INLINE_012(TYPE, FIELD) \ 79 DEFINE_SOURCE_ACCESSOR_INLINE(TYPE, FIELD, 0) \ 80 DEFINE_SOURCE_ACCESSOR_INLINE(TYPE, FIELD, 1) \ 81 DEFINE_SOURCE_ACCESSOR_INLINE(TYPE, FIELD, 2) 82 */ 83 #define DEFINE_GED_SOURCE_ACCESSORS_012(TYPE, FIELD) \ 84 DEFINE_SOURCE_ACCESSOR(TYPE, FIELD, 0) \ 85 DEFINE_SOURCE_ACCESSOR(TYPE, FIELD, 1) \ 86 DEFINE_SOURCE_ACCESSOR(TYPE, FIELD, 2) 87 88 89 namespace iga 90 { 91 struct FlagRegInfo { 92 Predication pred; 93 FlagModifier modifier; 94 RegRef reg; 95 }; 96 struct DirRegOpInfo { 97 RegName regName = RegName::INVALID; // e.g. "r" or "acc" 98 RegRef regRef; // 13 99 Type type = Type::INVALID; 100 }; 101 102 class Decoder : public GEDBitProcessor 103 { 104 public: 105 // Constructs a new decoder with an error handler and an empty kernel 106 Decoder(const Model &model, ErrorHandler &errHandler); 107 108 // the main entry point for decoding a kernel 109 Kernel *decodeKernelBlocks( 110 const void *binary, 111 size_t binarySize); 112 Kernel *decodeKernelNumeric( 113 const void *binary, 114 size_t binarySize); 115 116 // Set the SWSB endcoding mode, if not set, derived from platform setSWSBEncodingMode(SWSB_ENCODE_MODE mode)117 void setSWSBEncodingMode(SWSB_ENCODE_MODE mode) 118 { 119 if (mode != SWSB_ENCODE_MODE::SWSBInvalidMode) 120 { 121 m_SWSBEncodeMode = mode; 122 } 123 } 124 125 bool isMacro() const; 126 127 private: 128 Kernel *decodeKernel( 129 const void *binary, 130 size_t binarySize, 131 bool numericLabels); 132 133 // pass 1 decodes instructions with numeric labels 134 void decodeInstructions( 135 Kernel &kernel, 136 const void *binary, 137 size_t binarySize, 138 InstList &insts); 139 const OpSpec *decodeOpSpec(Op op); 140 141 Instruction *decodeNextInstruction(Kernel &kernel); 142 143 void decodeSWSB(Instruction* inst); 144 145 protected: 146 GED_ACCESS_MODE decodeAccessMode(); 147 MaskCtrl decodeMaskCtrl(); 148 Predication decodePredication(); 149 void decodePredInv(Predication& pred); 150 FlagRegInfo decodeFlagRegInfo(bool imm64Src0Overlap = false); // pred, cond, ... 151 ExecSize decodeExecSize(); 152 ChannelOffset decodeChannelOffset(); 153 154 void decodeJipToSrc( 155 Instruction *inst, 156 SourceIndex s = SourceIndex::SRC0, 157 Type type = Type::INVALID); 158 void decodeUipToSrc1(Instruction *inst, Type type); 159 int32_t decodeJip(); 160 int32_t decodeUip(); 161 162 // Reads a source from a the 'fromSrc'th source operand 163 // and creates the operand in IR as 'toSrc'. 164 // Typically this will be used directly as 165 // createSoureOp(inst, SourceIndex::SRC0, SourceIndex::SRC0); 166 // However, for some operands with implicit operands such as 167 // jmpi, ths will show up as 168 // createSoureOp(inst, SourceIndex::SRC1, SourceIndex::SRC0); 169 // since the first syntactic source is stored in src1's bits 170 // (src0 is ip for that op) 171 172 /////////////////////////////////////////////////////////////////////// 173 // BASIC INSTRUCTIONS 174 /////////////////////////////////////////////////////////////////////// 175 Instruction *decodeBasicInstruction(Kernel &kernel); 176 void decodeBasicUnaryInstruction(Instruction *inst, GED_ACCESS_MODE accessMode); 177 decodeBasicDestination(Instruction * inst,GED_ACCESS_MODE a)178 void decodeBasicDestination(Instruction *inst, GED_ACCESS_MODE a) { 179 if (a == GED_ACCESS_MODE_Align16) 180 decodeBasicDestinationAlign16(inst); 181 else 182 decodeBasicDestinationAlign1(inst); 183 } 184 void decodeBasicDestinationAlign16(Instruction *inst); // e.g. for math.invm and context save restore 185 void decodeBasicDestinationAlign1(Instruction *inst); 186 template <SourceIndex S> decodeSourceBasic(Instruction * inst,GED_ACCESS_MODE a)187 void decodeSourceBasic(Instruction *inst, GED_ACCESS_MODE a) { 188 if (a == GED_ACCESS_MODE_Align16) 189 decodeSourceBasicAlign16<S>(inst, S); 190 else 191 decodeSourceBasicAlign1<S>(inst, S); 192 } 193 template <SourceIndex S> decodeSourceBasic(Instruction * inst,SourceIndex toSrcIx,GED_ACCESS_MODE a)194 void decodeSourceBasic(Instruction *inst, SourceIndex toSrcIx, GED_ACCESS_MODE a) { 195 if (a == GED_ACCESS_MODE_Align16) 196 decodeSourceBasicAlign16<S>(inst, toSrcIx); 197 else 198 decodeSourceBasicAlign1<S>(inst, toSrcIx); 199 } 200 template <SourceIndex S> decodeSourceBasicAlign1(Instruction * inst)201 void decodeSourceBasicAlign1(Instruction *inst) { 202 decodeSourceBasicAlign1<S>(inst, S); 203 } 204 template <SourceIndex S> decodeSourceBasicAlign16(Instruction * inst)205 void decodeSourceBasicAlign16(Instruction *inst) { 206 decodeSourceBasicAlign16<S>(inst, S); 207 } 208 template <SourceIndex S> 209 void decodeSourceBasicAlign1(Instruction *inst, SourceIndex toSrcIx); 210 template <SourceIndex S> 211 void decodeSourceBasicAlign16(Instruction *inst, SourceIndex toSrcIx); 212 213 214 /////////////////////////////////////////////////////////////////////// 215 // TERNARY INSTRUCTIONS 216 /////////////////////////////////////////////////////////////////////// 217 Instruction *decodeTernaryInstruction(Kernel& kernel); 218 void decodeTernaryInstructionOperands(Kernel& kernel, Instruction *inst, GED_ACCESS_MODE accessMode); 219 // Align16 220 void decodeTernaryDestinationAlign16(Instruction *inst); 221 template <SourceIndex S> void decodeTernarySourceAlign16(Instruction *inst); 222 // Align1 223 void decodeTernaryDestinationAlign1(Instruction *inst); 224 template <SourceIndex S> void decodeTernarySourceAlign1(Instruction *inst); 225 226 /////////////////////////////////////////////////////////////////////// 227 // SEND INSTRUCTIONS 228 /////////////////////////////////////////////////////////////////////// 229 Instruction *decodeSendInstruction(Kernel &kernel); 230 void decodeSendDestination(Instruction *inst); 231 GED_ADDR_MODE decodeSendSource0AddressMode(); 232 void decodeSendSource0(Instruction *inst); 233 void decodeSendSource1(Instruction *inst); 234 SendDesc decodeSendExDesc(); 235 SendDesc decodeSendDesc(); 236 237 // facilitates internal decoding logic 238 struct SendDescodeInfo { 239 SFID sfid = SFID::INVALID; 240 int dstLen = -1, src0Len = -1, src1Len = -1; 241 bool hasCps = false, hasExBSO = false; 242 SendDesc desc, exDesc; 243 }; 244 void decodeSendInfoPreXe(SendDescodeInfo &sdi); 245 void decodeSendInfoXe(SendDescodeInfo &sdi); 246 void decodeSendInfoXeHP(SendDescodeInfo &sdi); 247 void decodeSendInfoXeHPG(SendDescodeInfo &sdi); 248 249 /////////////////////////////////////////////////////////////////////// 250 // BRANCH INSTRUCTIONS 251 /////////////////////////////////////////////////////////////////////// 252 Instruction *decodeBranchInstruction(Kernel &kernel); 253 Instruction *decodeBranchSimplifiedInstruction(Kernel &kernel); 254 void decodeBranchDestination(Instruction *inst); 255 256 /////////////////////////////////////////////////////////////////////// 257 // OTHER INSTRUCTIONS 258 /////////////////////////////////////////////////////////////////////// 259 Instruction *decodeWaitInstruction(Kernel &kernel); 260 Instruction *decodeSyncInstruction(Kernel &kernel); 261 262 /////////////////////////////////////////////////////////////////////// 263 // OTHER HELPERS 264 /////////////////////////////////////////////////////////////////////// 265 void decodeReg( 266 int opIx, // dst => opIx<0 267 GED_REG_FILE regFile, 268 uint32_t regNumBits, 269 RegName ®Name, 270 RegRef ®Ref); 271 272 273 DirRegOpInfo decodeDstDirRegInfo(); 274 Type decodeDstType(); 275 int decodeDestinationRegNumAccBitsFromChEn(); 276 MathMacroExt decodeDestinationMathMacroRegFromChEn(); 277 278 Subfunction decodeSubfunction(); 279 bool hasImm64Src0Overlap(); 280 281 void decodeDstDirSubRegNum(DirRegOpInfo& dri); 282 bool hasImplicitScalingType(Type& type, DirRegOpInfo& dri); 283 void decodeNextInstructionEpilog(Instruction *inst); 284 285 void decodeThreadOptions(Instruction *inst, GED_THREAD_CTRL trdCntrl); 286 287 template <SourceIndex S> ImmVal decodeTernarySrcImmVal(Type t); 288 289 // various GED source accessors 290 //some definitions created in Decoder.cpp using macros 291 //i.e. DEFINE_GED_SOURCE_ACCESSORS... 292 template <SourceIndex S> GED_ADDR_MODE decodeSrcAddrMode(); 293 294 //#define DEFINE_SOURCE_ACCESSOR_INLINE(TYPE, FIELD, I) 295 //template <> GED_ADDR_MODE decodeSrcAddrMode <SourceIndex::SRC0>() { 296 // RETURN_GED_DECODE_RAW_TO_SRC(GED_ADDR_MODE, Src0AddrMode); 297 //} 298 299 template <SourceIndex S> GED_REG_FILE decodeSrcRegFile(); 300 template <SourceIndex S> GED_DATA_TYPE decodeSrcDataType(); 301 302 // register direct fields 303 template <SourceIndex S> uint32_t decodeSrcRegNum(); 304 template <SourceIndex S> uint32_t decodeSrcSubRegNum(); 305 // implicit accumulators 306 template <SourceIndex S> GED_MATH_MACRO_EXT decodeSrcMathMacroExt(); 307 308 // register indirect fields 309 template <SourceIndex S> int32_t decodeSrcAddrImm(); 310 template <SourceIndex S> uint32_t decodeSrcAddrSubRegNum(); 311 // immediate fields 312 ImmVal decodeSrcImmVal(Type type); 313 314 // register direct and indirect fields 315 // yeah, the naming convention dictates this name 316 // (on for Src vs Dst) and one for the field name SrcMod 317 template <SourceIndex S> GED_SRC_MOD decodeSrcSrcMod(); 318 319 decodeSrcType()320 template <SourceIndex S> Type decodeSrcType() { 321 return translate(decodeSrcDataType<S>()); 322 } 323 decodeSrcRegionVWH()324 template <SourceIndex S> Region decodeSrcRegionVWH() { 325 return transateGEDtoIGARegion( 326 decodeSrcVertStride<S>(), 327 decodeSrcWidth<S>(), 328 decodeSrcHorzStride<S>()); 329 } 330 331 template <SourceIndex S> Region decodeSrcRegionTernaryAlign1(const OpSpec &); 332 decodeSrcMathMacroReg()333 template <SourceIndex S> MathMacroExt decodeSrcMathMacroReg() { 334 return translate(decodeSrcMathMacroExt<S>()); 335 } decodeSrcModifier()336 template <SourceIndex S> SrcModifier decodeSrcModifier() { 337 if (m_opSpec->supportsSourceModifiers()) { 338 return translate(decodeSrcSrcMod<S>()); 339 } 340 return SrcModifier::NONE; 341 } 342 343 // decodes regname, regnum, and subreg num (if applicable) 344 // does *not* scale the subreg num decodeSourceReg(RegRef & regRef)345 template <SourceIndex S> RegName decodeSourceReg(RegRef ®Ref) { 346 uint32_t regNumBits = decodeSrcRegNum<S>(); 347 RegName regName = RegName::INVALID; 348 GED_REG_FILE regFile = decodeSrcRegFile<S>(); 349 decodeReg((int)S, regFile, regNumBits, regName, regRef); 350 if (!m_opSpec->isSendOrSendsFamily() && !isMacro()) { 351 regRef.subRegNum = (uint16_t)decodeSrcSubRegNum<S>(); 352 } else { 353 regRef.subRegNum = 0; 354 } 355 return regName; 356 } 357 decodeSrcDirRegOpInfo()358 template <SourceIndex S> DirRegOpInfo decodeSrcDirRegOpInfo() { 359 DirRegOpInfo dri; 360 dri.regName = decodeSourceReg<S>(dri.regRef); 361 362 Type scalingType = Type::INVALID; 363 // FIXME: not sure what "hasImplicitScalingType" for, this cause the in-consistent 364 // between encoder and decoder. Still using it to keep it the same as before... 365 if (!hasImplicitScalingType(scalingType, dri)) { 366 scalingType = dri.type = decodeSrcType<S>(); 367 } 368 369 if (scalingType == Type::INVALID) { 370 scalingType = Type::UB; 371 if (m_opSpec->isBranching()) 372 scalingType = Type::D; 373 } 374 375 dri.regRef.subRegNum = (uint16_t)BinaryOffsetToSubReg( 376 dri.regRef.subRegNum, dri.regName, 377 scalingType, m_model.platform); 378 379 return dri; 380 } 381 382 template <SourceIndex S> uint32_t decodeSrcVertStride(); 383 template <SourceIndex S> uint32_t decodeSrcWidth(); 384 template <SourceIndex S> uint32_t decodeSrcHorzStride(); 385 template <SourceIndex S> uint32_t decodeSrcChanSel(); 386 template <SourceIndex S> GED_REP_CTRL decodeSrcRepCtrl(); 387 template <SourceIndex S> uint8_t decodeSrcCtxSvRstAccBitsToRegNum(); 388 void decodeChSelToSwizzle(uint32_t chanSel, GED_SWIZZLE swizzle[4]); 389 template <SourceIndex S> bool isChanSelPacked(); 390 391 void decodeOptions(Instruction *inst); 392 393 protected: 394 GED_MODEL m_gedModel; 395 396 // decode-level state (valid below decodeKernel variants) 397 Kernel *m_kernel; 398 399 // state shared below decodeInstToBlock() 400 // info about the instruction being converted to IGA IR 401 ged_ins_t m_currGedInst; 402 const OpSpec *m_opSpec; 403 Subfunction m_subfunc; 404 const void *m_binary; 405 406 // SWSB encoding mode 407 SWSB_ENCODE_MODE m_SWSBEncodeMode = SWSB_ENCODE_MODE::SWSBInvalidMode; 408 409 // for GED workarounds: grab specific bits from the current instruction 410 uint32_t getBitField(int ix, int len) const; 411 412 // helper for inserting instructions for decode errors 413 Instruction *createErrorInstruction( 414 Kernel &kernel, 415 const char *message, 416 const void *binary, 417 int32_t iLen); 418 419 // used by the GED_DECODE macros 420 void handleGedDecoderError( 421 int line, 422 const char *field, 423 GED_RETURN_VALUE status); 424 }; // end class Decoder 425 426 427 428 } //end: namespace iga* 429 430 namespace iga 431 { 432 typedef Decoder Decoder; 433 } 434 435 #endif //end: _IGA_DECODER_H_ 436