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