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_INSTRUCTION_HPP_ 10 #define _IGA_INSTRUCTION_HPP_ 11 12 // WARNING: the IR is subject to change without any notice. External tools 13 // should use the official interfaces in the external API. Those interfaces 14 // are tested between releases and maintained even with changes to the IR. 15 16 #include "../MemManager/MemManager.hpp" 17 18 #include "../Models/Models.hpp" 19 #include "Operand.hpp" 20 #include "Loc.hpp" 21 #include "Types.hpp" 22 #include "../EnumBitset.hpp" 23 #include "../asserts.hpp" 24 25 #include <string> 26 27 namespace iga 28 { 29 enum class SourceIndex { 30 SRC0 = 0, 31 SRC1 = 1, 32 SRC2 = 2, 33 }; 34 35 // represents a GEN instruction 36 class Instruction 37 { 38 public: Instruction(int id,PC pc,Loc loc,const OpSpec & os)39 Instruction( 40 int id, 41 PC pc, 42 Loc loc, 43 const OpSpec &os) 44 : Instruction( 45 os, ExecSize::INVALID, ChannelOffset::M0, MaskCtrl::NORMAL) 46 { 47 setID(id); 48 setLoc(loc); 49 setPC(pc); 50 } 51 52 // TODO: phase this constructor out Instruction(const OpSpec & os,ExecSize execSize,ChannelOffset chOff,MaskCtrl mc)53 Instruction( 54 const OpSpec &os, 55 ExecSize execSize, 56 ChannelOffset chOff, 57 MaskCtrl mc) 58 : m_opSpec(os) 59 , m_sf(InvalidFC::INVALID) 60 , m_maskCtrl(mc) 61 , m_pred(PredCtrl::NONE,false) 62 , m_flagReg(REGREF_ZERO_ZERO) 63 , m_execSize(execSize) 64 , m_chOff(chOff) 65 , m_flagModifier(FlagModifier::NONE) 66 , m_instLoc(Loc::INVALID) 67 , m_instId(0xFFFFFFFF) 68 , m_pc(0) 69 , m_sendDstLength(-1) 70 , m_sendSrc0Length(-1) 71 , m_sendSrc1Length(-1) 72 { 73 } 74 Instruction(const Instruction &) = delete; 75 76 // for placement allocation operator delete(void *,MemManager *)77 void operator delete(void *, MemManager*) { } operator new(size_t sz,MemManager * m)78 void *operator new(size_t sz, MemManager* m) {return m->alloc(sz);} 79 80 /////////////////////////////////////////////////////////////////////// 81 // operations that set instruction state 82 // (these are kept roughly in syntax order; 83 // e.g. predication before instruction options) 84 // setLoc(const Loc & loc)85 void setLoc(const Loc &loc) {m_instLoc = loc;} setPC(int32_t pc)86 void setPC(int32_t pc) {m_pc = pc;} setID(int id)87 void setID(int id) {m_instId = id;} setMaskCtrl(MaskCtrl mc)88 void setMaskCtrl(MaskCtrl mc) {m_maskCtrl = mc;} setExecSize(ExecSize es)89 void setExecSize(ExecSize es) {m_execSize = es;} setChannelOffset(ChannelOffset co)90 void setChannelOffset(ChannelOffset co) {m_chOff = co;} setFlagModifier(FlagModifier flagModifier)91 void setFlagModifier(FlagModifier flagModifier) {m_flagModifier = flagModifier;} setFlagReg(RegRef reg)92 void setFlagReg(RegRef reg) {m_flagReg = reg;} setPredication(const Predication & predOpnd)93 void setPredication(const Predication &predOpnd) {m_pred = predOpnd;} 94 95 void setSubfunction(Subfunction sf); 96 97 void setDirectDestination( 98 DstModifier dstMod, 99 RegName r, 100 RegRef reg, 101 Region::Horz rgn, 102 Type type); 103 void setMacroDestination( 104 DstModifier dstMod, 105 RegName r, 106 RegRef reg, 107 MathMacroExt mme, 108 Region::Horz rgn, 109 Type type); 110 void setInidirectDestination( 111 DstModifier dstMod, 112 RegRef addrReg, 113 int16_t addrImmOff, 114 Region::Horz rgnH, 115 Type type); 116 void setDirectSource( 117 SourceIndex srcIx, 118 SrcModifier srcMod, 119 RegName rType, 120 RegRef reg, 121 Region rgn, 122 Type type); 123 void setInidirectSource( 124 SourceIndex srcIx, 125 SrcModifier srcMod, 126 RegName regName, 127 RegRef reg, 128 int16_t m_immOffset, 129 Region rgn, 130 Type type); 131 void setMacroSource( 132 SourceIndex srcIx, 133 SrcModifier srcMod, 134 RegName r, 135 RegRef reg, 136 MathMacroExt acc, 137 Region rgn, 138 Type type); 139 void setImmediateSource( 140 SourceIndex srcIx, 141 const ImmVal &val, 142 Type type); 143 void setLabelSource( 144 SourceIndex srcIx, 145 Block *jip, 146 Type type = Type::INVALID); 147 void setLabelSource( 148 SourceIndex srcIx, 149 int32_t pc, 150 Type type = Type::INVALID); 151 // e.g. pass Operand::NULL_UD_SRC 152 void setSource(SourceIndex srcIx, const Operand &op); 153 setExtMsgDesc(const SendDesc & msg)154 void setExtMsgDesc(const SendDesc &msg) {m_exDesc = msg;} setMsgDesc(const SendDesc & msg)155 void setMsgDesc(const SendDesc &msg) {m_desc = msg;} 156 setDstLength(int dstLength)157 void setDstLength(int dstLength) {m_sendDstLength = dstLength;} setSrc0Length(int src0Length)158 void setSrc0Length(int src0Length) {m_sendSrc0Length = src0Length;} setSrc1Length(int src1Length)159 void setSrc1Length(int src1Length) {m_sendSrc1Length = src1Length;} 160 setSWSB(SWSB swsb)161 void setSWSB(SWSB swsb) {m_depInfo = swsb;} 162 addInstOpt(const InstOpt & opt)163 void addInstOpt(const InstOpt &opt) {m_instOpts.add(opt);} addInstOpts(const InstOptSet & opts)164 void addInstOpts(const InstOptSet &opts) {m_instOpts.add(opts);} 165 166 // associates an optional comment with instruction setComment(std::string comment)167 void setComment(std::string comment) {m_comment = comment;} 168 169 /////////////////////////////////////////////////////////////////////// 170 // name lacks get*** for consistency with other classes that all use 171 // just "platform()" platform() const172 Platform platform() const {return m_opSpec.platform;} 173 const Model &model() const; 174 175 /////////////////////////////////////////////////////////////////////// 176 // operations that get instruction state 177 // 178 // the source or binary location getLoc() const179 const Loc &getLoc() const {return m_instLoc;} getID() const180 int getID() const {return m_instId;} getPC() const181 PC getPC() const {return m_pc;} 182 183 // returns the instruction op specification getOpSpec() const184 const OpSpec &getOpSpec() const {return m_opSpec;} 185 // opcode, math function control, and branch control getOp() const186 Op getOp() const {return m_opSpec.op;} is(Op op) const187 bool is(Op op) const {return m_opSpec.is(op);} 188 189 // WrEn (NoMask) getMaskCtrl() const190 MaskCtrl getMaskCtrl() const {return m_maskCtrl;} 191 // predication hasPredication() const192 bool hasPredication() const {return m_pred.function != PredCtrl::NONE;} getPredication() const193 const Predication& getPredication() const {return m_pred;} 194 195 /////////////////////////////////////////////////////////// 196 // subfunction accessors getSubfunction() const197 Subfunction getSubfunction() const {return m_sf;} 198 // specific subfunction accessors 199 // TODO: tantrum (assert) if they call one on the wrong op? getBranchCtrl() const200 BranchCntrl getBranchCtrl() const {return m_sf.branch;} getMathFc() const201 MathFC getMathFc() const {return m_sf.math;} getSendFc() const202 SFID getSendFc() const {return m_sf.send;} getSyncFc() const203 SyncFC getSyncFc() const {return m_sf.sync;} getBfnFc() const204 BfnFC getBfnFc() const {return m_sf.bfn;} getDpasFc() const205 DpasFC getDpasFc() const {return m_sf.dpas;} 206 207 // true for madm or math.invm and math.rsqrtm 208 bool isMacro() const; 209 // execution width info getExecSize() const210 ExecSize getExecSize() const {return m_execSize;} getChannelOffset() const211 ChannelOffset getChannelOffset() const {return m_chOff;} 212 213 // returns if the instruction has a flag (condition) modifier hasFlagModifier() const214 bool hasFlagModifier() const {return m_flagModifier != FlagModifier::NONE;} getFlagModifier() const215 FlagModifier getFlagModifier() const {return m_flagModifier;} 216 217 // flag register is shared by predication and flag modfier getFlagReg() const218 const RegRef& getFlagReg() const {return m_flagReg;} 219 getDestination() const220 const Operand& getDestination() const {return m_dst;} getDestination()221 Operand& getDestination() {return m_dst;} getSource(size_t srcNum) const222 const Operand& getSource(size_t srcNum) const {return m_srcs[srcNum];} getSource(size_t srcNum)223 Operand& getSource(size_t srcNum) {return m_srcs[srcNum];} getSource(SourceIndex srcNum) const224 const Operand& getSource(SourceIndex srcNum) const {return m_srcs[(int)srcNum];} getSource(SourceIndex srcNum)225 Operand& getSource(SourceIndex srcNum) {return m_srcs[(int)srcNum];} 226 227 unsigned getSourceCount() const; 228 getExtMsgDescriptor() const229 SendDesc getExtMsgDescriptor() const {return m_exDesc;} getMsgDescriptor() const230 SendDesc getMsgDescriptor() const {return m_desc;} 231 // (For send messages) this returns the dst payload length in registers 232 // as encoded by the descriptors (if known). getDstLength() const233 int getDstLength() const {return m_sendDstLength;} 234 // (For send messages) this returns the src0 payload length in registers 235 // as encoded by the descriptors (if known). getSrc0Length() const236 int getSrc0Length() const {return m_sendSrc0Length;} 237 // (For send messages) this returns the src1 payload length in registers 238 // as encoded by the descriptors (if known). getSrc1Length() const239 int getSrc1Length() const {return m_sendSrc1Length;} 240 getInstOpts() const241 const InstOptSet& getInstOpts() const {return m_instOpts;} hasInstOpt(InstOpt opt) const242 bool hasInstOpt(InstOpt opt) const {return m_instOpts.contains(opt);} removeInstOpt(InstOpt opt)243 void removeInstOpt(InstOpt opt) {m_instOpts.remove(opt);} 244 getJIP() const245 const Block *getJIP() const {return m_srcs[0].getTargetBlock();} getUIP() const246 const Block *getUIP() const {return m_srcs[1].getTargetBlock();} getComment() const247 const std::string &getComment() const {return m_comment;} getSWSB() const248 SWSB getSWSB() const {return m_depInfo;} isBranching() const249 bool isBranching() const {return getOpSpec().isBranching();} 250 251 bool isMovWithLabel() const; 252 253 254 SWSB::InstType getSWSBInstType(SWSB_ENCODE_MODE mode) const; 255 256 void validate() const; // asserts on malformed IR 257 std::string str() const; // returns syntax of this instruction 258 private: 259 const OpSpec& m_opSpec; // information about the specific inst op 260 Subfunction m_sf; // e.g. MathFC::INV for math.inv, SFID::DC0 for send.dc0 261 262 MaskCtrl m_maskCtrl; // (W) WrEn (write enable / NoMask) 263 Predication m_pred; // predication function (and logical sign) 264 RegRef m_flagReg; // shared by m_pred and m_flagModifier 265 266 ExecSize m_execSize; 267 ChannelOffset m_chOff; 268 Operand m_dst; 269 Operand m_srcs[3]; 270 271 FlagModifier m_flagModifier; // conditional-modifier function 272 273 SendDesc m_exDesc; 274 SendDesc m_desc; 275 // These fields are best-effort decodes of the message lengths 276 // E.g. if the fields are buried in an immediate send descriptor, 277 // extract them here. In some cases (e.g. reg descriptors), we can't 278 // help you. Oppose architects that propose instruction definitions 279 // that are taken form registers. 280 int m_sendDstLength; // -1 if unknown 281 int m_sendSrc0Length; // -1 if unknown 282 int m_sendSrc1Length; // -1 if unknown 283 284 InstOptSet m_instOpts; // miscellaneous instruction attributes 285 SWSB m_depInfo; 286 287 int m_instId; // unique id for this instruction 288 // (unique in the kernel) 289 290 int32_t m_pc; // the encode/decode PC for this instruction 291 Loc m_instLoc; // source location info we keep this 292 // separate from the PC since we 293 // use both during assembly 294 295 // e.g. for illegal instruction extended info (e.g. decode errors) 296 // enables us to emit things like 297 // illegal {Compacted} // failed to uncompact .... 298 // ^^^^^^^^^^^^^^^^^^^ 299 std::string m_comment; 300 }; // class Instruction 301 } // namespace iga 302 #endif //_IGA_INSTRUCTION_HPP_ 303