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 #include "Instruction.hpp"
10 #include "Types.hpp"
11 #include "Checker/IRChecker.hpp"
12 #include "../Frontend/Formatter.hpp"
13 
14 #include <sstream>
15 
16 using namespace iga;
17 
setSubfunction(Subfunction sf)18 void Instruction::setSubfunction(Subfunction sf) {
19     IGA_ASSERT(!getOpSpec().supportsSubfunction() || sf.isValid(),
20         "instruction given invalid subfunction");
21     IGA_ASSERT(getOpSpec().supportsSubfunction() || !sf.isValid(),
22         "instruction forbids subfunction");
23     m_sf = sf;
24 }
25 
26 
setDirectDestination(DstModifier dstMod,RegName rnm,RegRef reg,Region::Horz rgnH,Type type)27 void Instruction::setDirectDestination(
28     DstModifier dstMod,
29     RegName rnm,
30     RegRef reg,
31     Region::Horz rgnH,
32     Type type)
33 {
34     if (getOpSpec().isSendOrSendsFamily() &&
35         m_sendDstLength < 0 &&
36         rnm == RegName::ARF_NULL)
37     {
38         m_sendDstLength = 0;
39     }
40     m_dst.setDirectDestination(dstMod, rnm, reg, rgnH, type);
41 }
42 
43 
setMacroDestination(DstModifier dstMod,RegName rnm,RegRef reg,MathMacroExt mme,Region::Horz rgnHz,Type type)44 void Instruction::setMacroDestination(
45     DstModifier dstMod,
46     RegName rnm,
47     RegRef reg,
48     MathMacroExt mme,
49     Region::Horz rgnHz,
50     Type type)
51 {
52     m_dst.setMacroDestination(dstMod, rnm, reg, mme, rgnHz, type);
53 }
54 
55 
setInidirectDestination(DstModifier dstMod,RegRef reg,int16_t addrImmOff,Region::Horz rgnH,Type type)56 void Instruction::setInidirectDestination(
57     DstModifier dstMod,
58     RegRef reg,
59     int16_t addrImmOff,
60     Region::Horz rgnH,
61     Type type)
62 {
63     m_dst.setInidirectDestination(dstMod, reg, addrImmOff, rgnH, type);
64 }
65 
66 
setDirectSource(SourceIndex srcIx,SrcModifier srcMod,RegName rnm,RegRef reg,Region rgn,Type type)67 void Instruction::setDirectSource(
68     SourceIndex srcIx,
69     SrcModifier srcMod,
70     RegName rnm,
71     RegRef reg,
72     Region rgn,
73     Type type)
74 {
75     unsigned ix = static_cast<unsigned>(srcIx);
76     if (getOpSpec().isSendOrSendsFamily() &&
77         rnm == RegName::ARF_NULL)
78     {
79         // send with a null operand must have a 0 length
80         // we only check this if we didn't get the length via the
81         // descriptor
82         if (ix == 0 && m_sendSrc0Length < 0)
83             m_sendSrc0Length = 0;
84         else if (ix == 1 && m_sendSrc1Length < 0)
85             m_sendSrc1Length = 0;
86     }
87     m_srcs[ix].setDirectSource(srcMod, rnm, reg, rgn, type);
88 }
89 
90 
setMacroSource(SourceIndex srcIx,SrcModifier srcMod,RegName rName,RegRef reg,MathMacroExt acc,Region rgn,Type type)91 void Instruction::setMacroSource(
92     SourceIndex srcIx,
93     SrcModifier srcMod,
94     RegName rName,
95     RegRef reg,
96     MathMacroExt acc,
97     Region rgn,
98     Type type)
99 {
100     unsigned ix = static_cast<unsigned>(srcIx);
101     m_srcs[ix].setMacroSource(srcMod, rName, reg, acc, rgn, type);
102 }
103 
setInidirectSource(SourceIndex srcIx,SrcModifier srcMod,RegName regName,RegRef reg,int16_t immediateOffset,Region rgn,Type type)104 void Instruction::setInidirectSource(
105     SourceIndex srcIx,
106     SrcModifier srcMod,
107     RegName regName,
108     RegRef reg,
109     int16_t immediateOffset,
110     Region rgn,
111     Type type)
112 {
113     unsigned ix = static_cast<unsigned>(srcIx);
114     m_srcs[ix].setInidirectSource(srcMod, regName, reg, immediateOffset, rgn, type);
115 }
116 
117 
setImmediateSource(SourceIndex srcIx,const ImmVal & val,Type type)118 void Instruction::setImmediateSource(
119     SourceIndex srcIx, const ImmVal &val, Type type)
120 {
121     unsigned ix = static_cast<unsigned>(srcIx);
122     m_srcs[ix].setImmediateSource(val, type);
123 }
124 
125 
setLabelSource(SourceIndex srcIx,int32_t pc,Type type)126 void Instruction::setLabelSource(SourceIndex srcIx, int32_t pc, Type type)
127 {
128     unsigned ix = static_cast<unsigned>(srcIx);
129     m_srcs[ix].setLabelSource(pc, type);
130 }
setLabelSource(SourceIndex srcIx,Block * block,Type type)131 void Instruction::setLabelSource(SourceIndex srcIx, Block *block, Type type)
132 {
133     unsigned ix = static_cast<unsigned>(srcIx);
134     m_srcs[ix].setLabelSource(block, type);
135 }
136 
137 
setSource(SourceIndex srcIx,const Operand & op)138 void Instruction::setSource(SourceIndex srcIx, const Operand &op)
139 {
140     unsigned ix = static_cast<unsigned>(srcIx);
141     if (getOpSpec().isSendOrSendsFamily() &&
142         op.getKind() == Operand::Kind::DIRECT &&
143         op.getDirRegName() == RegName::ARF_NULL)
144     {
145         // send with a null operand must have a 0 length
146         // we only check this if we didn't get the length via the
147         // descriptor
148         if (ix == 0 && m_sendSrc0Length < 0)
149             m_sendSrc0Length = 0;
150         else if (ix == 1 && m_sendSrc1Length < 0)
151             m_sendSrc1Length = 0;
152     }
153     m_srcs[ix] = op;
154 }
155 
model() const156 const Model &Instruction::model() const {
157     return Model::LookupModelRef(platform());
158 }
159 
getSWSBInstType(SWSB_ENCODE_MODE mode) const160 SWSB::InstType Instruction::getSWSBInstType(SWSB_ENCODE_MODE mode) const {
161     if (mode == SWSB_ENCODE_MODE::SWSBInvalidMode)
162         return SWSB::InstType::UNKNOWN;
163 
164     if (getOpSpec().isSendOrSendsFamily())
165         return SWSB::InstType::SEND;
166 
167     if (is(Op::MATH))
168         return SWSB::InstType::MATH;
169 
170 
171     if (getOpSpec().isDpasFamily()) {
172         return SWSB::InstType::DPAS;
173     }
174 
175     return SWSB::InstType::OTHERS;
176 }
177 
isMacro() const178 bool Instruction::isMacro() const {
179     return is(Op::MADM) || (is(Op::MATH) && IsMacro(m_sf.math));
180 }
181 
182 
isMovWithLabel() const183 bool Instruction::isMovWithLabel() const {
184     return (getOp() == Op::MOV &&
185         getSource(0).getKind() == Operand::Kind::LABEL);
186 }
187 
188 
validate() const189 void Instruction::validate() const
190 {
191     iga::SanityCheckIR(*this);
192 }
193 
str() const194 std::string Instruction::str() const
195 {
196     ErrorHandler eh;
197     std::stringstream ss;
198     FormatOpts fopt(model());
199     fopt.setSWSBEncodingMode(
200         Model::LookupModelRef(getOpSpec().platform).getSWSBEncodeMode());
201     FormatInstruction(eh, ss, fopt, *this);
202     return ss.str();
203 }
204 
getSourceCountBrc(const Instruction & i)205 static unsigned getSourceCountBrc(const Instruction &i)
206 {
207     // brc (..) IMM IMM
208     // brc (..) REG
209     switch (i.getSource(0).getKind()) {
210     case Operand::Kind::DIRECT:
211     case Operand::Kind::INDIRECT:
212         return 1;
213     default:
214         return 2;
215     }
216 }
217 
getSourceCount() const218 unsigned Instruction::getSourceCount() const
219 {
220     // BRC can have 1 or 2 operands, everyone else is simple
221     if (is(Op::BRC)) {
222         return getSourceCountBrc(*this);
223     } else {
224         return getOpSpec().getSourceCount(getSubfunction());
225     }
226 }
227