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