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 "FlowGraph.h"
10 using namespace vISA;
11
12 /* G4_SrcRegRegion */
13
ExRegNum(bool & valid) const14 unsigned short G4_SrcRegRegion::ExRegNum(bool &valid) const {
15 short normRegNum = 0;
16 short registerOffset = (regOff == (short)UNDEFINED_SHORT)? 0: regOff;
17 short subRegisterOffset = (subRegOff == (short)UNDEFINED_SHORT)? 0: subRegOff;
18 if (base->isRegVar())
19 {
20 G4_RegVar* baseVar = static_cast<G4_RegVar*>(base);
21 if (baseVar->isPhyRegAssigned() && baseVar->getPhyReg()->isGreg()) // Greg
22 {
23 valid = true;
24 unsigned RegNum = (static_cast<G4_Greg*>(baseVar->getPhyReg()))->getRegNum();
25 unsigned SubRegNum = baseVar->getPhyRegOff();
26
27 int declOpSize = TypeSize(baseVar->getDeclare()->getElemType());
28 int thisOpSize = TypeSize(type);
29
30 if (thisOpSize != declOpSize)
31 {
32 MUST_BE_TRUE((SubRegNum * declOpSize) % thisOpSize == 0,
33 ERROR_DATA_RANGE("sub-register number"));
34 SubRegNum = (SubRegNum * declOpSize) / thisOpSize;
35 }
36 short regnum = (SubRegNum + subRegisterOffset) / (32 / thisOpSize);
37 normRegNum = RegNum + registerOffset + regnum;
38 MUST_BE_TRUE(normRegNum>=0,
39 ERROR_DATA_RANGE("register number"));
40 return ((unsigned short)normRegNum);
41 }
42 }
43 normRegNum = base->ExRegNum(valid)+registerOffset;
44 MUST_BE_TRUE(normRegNum>=0,
45 ERROR_DATA_RANGE("register number"));
46 return ((unsigned short)normRegNum);
47 }
48
ExSubRegNum(bool & valid)49 unsigned short G4_SrcRegRegion::ExSubRegNum(bool &valid) {
50 valid = true;
51 unsigned short subRegNum = 0;
52 short normSubRegNum = 0;
53 short subRegisterOffset = (subRegOff == (short)UNDEFINED_SHORT)? 0: subRegOff;
54 if (base->isRegVar())
55 {
56 G4_RegVar* baseVar = static_cast<G4_RegVar*>(base);
57 if (baseVar->isPhyRegAssigned() && baseVar->getPhyReg()->isAreg())
58 {
59 normSubRegNum = baseVar->getPhyRegOff() + subRegisterOffset;
60 MUST_BE_TRUE(normSubRegNum>=0,
61 ERROR_DATA_RANGE("sub-register number"));
62 subRegNum = (unsigned short) normSubRegNum;
63 if (acc == Direct)
64 {
65 MUST_BE_TRUE(regOff == 0,
66 ERROR_DATA_RANGE("register offset"));
67 int thisOpSize = getTypeSize();
68 int declOpSize = TypeSize(baseVar->getDeclare()->getElemType());
69 if (thisOpSize > declOpSize)
70 {
71 MUST_BE_TRUE((thisOpSize/declOpSize) == 2 || (thisOpSize/declOpSize) == 4,
72 ERROR_DATA_RANGE("operand size"));
73 unsigned shiftVal = ((thisOpSize/declOpSize) == 2) ? 1 : 2;
74 subRegNum >>= shiftVal;
75 }
76 else if (thisOpSize < declOpSize)
77 {
78 MUST_BE_TRUE((declOpSize/thisOpSize) == 2 || (declOpSize/thisOpSize) == 4,
79 ERROR_DATA_RANGE("operand size"));
80 unsigned shiftVal = ((declOpSize/thisOpSize) == 2) ? 1 : 2;
81 subRegNum <<= shiftVal;
82 }
83 return subRegNum;
84 }
85 }
86 else if (baseVar->isPhyRegAssigned() &&
87 (baseVar->getPhyReg()->isGreg()))
88 {
89 normSubRegNum = (short)baseVar->getPhyRegOff();
90
91 int thisOpSize = getTypeSize();
92 int declOpSize = TypeSize(baseVar->getDeclare()->getElemType());
93
94 if (thisOpSize != declOpSize)
95 {
96 MUST_BE_TRUE((normSubRegNum * declOpSize) % thisOpSize == 0,
97 ERROR_DATA_RANGE("sub-register number"));
98 normSubRegNum = (normSubRegNum * declOpSize) / thisOpSize;
99 }
100 normSubRegNum = (normSubRegNum + subRegisterOffset) % (32 / thisOpSize);
101 MUST_BE_TRUE(normSubRegNum>=0,
102 ERROR_DATA_RANGE("sub-register number"));
103 subRegNum = (unsigned short) normSubRegNum;
104 return subRegNum;
105 }
106 }
107 normSubRegNum = subRegisterOffset;
108 MUST_BE_TRUE(normSubRegNum>=0,
109 ERROR_DATA_RANGE("sub-register number"));
110 subRegNum = (unsigned short) normSubRegNum;
111 if (subRegOff == (short)UNDEFINED_SHORT)
112 valid = false;
113 return subRegNum;
114 }
115
ExIndSubRegNum(bool & valid)116 unsigned short G4_SrcRegRegion::ExIndSubRegNum(bool &valid) {
117 if (base->isRegVar())
118 {
119 short subRegisterOffset = (subRegOff == (short)UNDEFINED_SHORT)? 0: subRegOff;
120 short normSubRegNum = (static_cast<G4_RegVar*>(base)->getPhyRegOff() + subRegisterOffset);
121 MUST_BE_TRUE(normSubRegNum>=0,
122 ERROR_DATA_RANGE("sub-register number"));
123 return ((unsigned short) normSubRegNum);
124 }
125 return ExSubRegNum(valid);
126 }
127
ExIndImmVal(void)128 short G4_SrcRegRegion::ExIndImmVal(void) {
129 return immAddrOff;
130 }
131
132 /* G4_DstRegRegion */
133
ExRegNum(bool & valid)134 unsigned short G4_DstRegRegion::ExRegNum(bool &valid) {
135 short normRegNum = 0;
136 short registerOffset = (regOff == (short)UNDEFINED_SHORT)? 0: regOff;
137 short subRegisterOffset = (subRegOff == (short)UNDEFINED_SHORT)? 0: subRegOff;
138 if (base->isRegVar())
139 {
140 G4_RegVar* baseVar = static_cast<G4_RegVar*>(base);
141 if (baseVar->isPhyRegAssigned() && baseVar->getPhyReg()->isGreg())
142 {
143 valid = true;
144 unsigned RegNum = (static_cast<G4_Greg*>(baseVar->getPhyReg()))->getRegNum();
145 unsigned SubRegNum = baseVar->getPhyRegOff();
146
147 int declOpSize = TypeSize(baseVar->getDeclare()->getElemType());
148 int thisOpSize = TypeSize(type);
149
150 if (thisOpSize != declOpSize)
151 {
152 MUST_BE_TRUE((SubRegNum * declOpSize) % thisOpSize == 0,
153 ERROR_DATA_RANGE("operand size"));
154 SubRegNum = (SubRegNum * declOpSize) / thisOpSize;
155 }
156 short regnum = (SubRegNum + subRegisterOffset) / (32 / thisOpSize);
157 normRegNum = RegNum + registerOffset + regnum;
158 MUST_BE_TRUE(normRegNum>=0,
159 ERROR_DATA_RANGE("register number"));
160 return ((unsigned short)normRegNum);
161 }
162 }
163 normRegNum = base->ExRegNum(valid)+registerOffset;
164 MUST_BE_TRUE(normRegNum>=0,
165 ERROR_DATA_RANGE("register number"));
166 return ((unsigned short)normRegNum);
167 }
168
ExSubRegNum(bool & valid)169 unsigned short G4_DstRegRegion::ExSubRegNum(bool &valid) {
170 valid = true;
171 unsigned short subRegNum = 0;
172 short normSubRegNum = 0;
173 short subRegisterOffset = (subRegOff == (short)UNDEFINED_SHORT)? 0: subRegOff;
174 if (base->isRegVar())
175 {
176 G4_RegVar* baseVar = static_cast<G4_RegVar*>(base);
177 if (baseVar->isPhyRegAssigned() && baseVar->getPhyReg()->isAreg())
178 {
179 normSubRegNum = baseVar->getPhyRegOff() + subRegisterOffset;
180 MUST_BE_TRUE(normSubRegNum>=0,
181 ERROR_DATA_RANGE("sub-register number"));
182 subRegNum = (unsigned short) normSubRegNum;
183 if (acc == Direct)
184 {
185 MUST_BE_TRUE(regOff == 0,
186 ERROR_DATA_RANGE("register offset"));
187 int thisOpSize = getTypeSize();
188 int declOpSize = TypeSize(baseVar->getDeclare()->getElemType());
189 if (thisOpSize > declOpSize)
190 {
191 MUST_BE_TRUE((thisOpSize/declOpSize) == 2 || (thisOpSize/declOpSize) == 4 || (thisOpSize / declOpSize) == 8,
192 ERROR_DATA_RANGE("operand size"));
193 unsigned shiftVal = ((thisOpSize/declOpSize) == 2) ? 1 : 2;
194 subRegNum >>= shiftVal;
195 }
196 else if (thisOpSize < declOpSize)
197 {
198 MUST_BE_TRUE((declOpSize/thisOpSize) == 2 || (declOpSize/thisOpSize) == 4,
199 ERROR_DATA_RANGE("operand size"));
200 unsigned shiftVal = ((declOpSize/thisOpSize) == 2) ? 1 : 2;
201 subRegNum <<= shiftVal;
202 }
203 return subRegNum;
204 }
205 }
206 else if (baseVar->isPhyRegAssigned() &&
207 (baseVar->getPhyReg()->isGreg()))
208 {
209 normSubRegNum = (short)baseVar->getPhyRegOff();
210
211 int thisOpSize = getTypeSize();
212 int declOpSize = TypeSize(baseVar->getDeclare()->getElemType());
213
214 if (thisOpSize != declOpSize)
215 {
216 MUST_BE_TRUE((normSubRegNum * declOpSize) % thisOpSize == 0,
217 ERROR_DATA_RANGE("operand size"));
218 normSubRegNum = (normSubRegNum * declOpSize) / thisOpSize;
219 }
220 normSubRegNum = (normSubRegNum + subRegisterOffset) % (32 / thisOpSize);
221 MUST_BE_TRUE(normSubRegNum>=0,
222 ERROR_DATA_RANGE("sub-register number"));
223 subRegNum = (unsigned short) normSubRegNum;
224 return subRegNum;
225 }
226 }
227 normSubRegNum = subRegisterOffset;
228 MUST_BE_TRUE(normSubRegNum>=0,
229 ERROR_DATA_RANGE("sub-register number"));
230 subRegNum = (unsigned short) normSubRegNum;
231 if (subRegOff == (short)UNDEFINED_SHORT)
232 valid = false;
233 return subRegNum;
234 }
235
ExIndSubRegNum(bool & valid)236 unsigned short G4_DstRegRegion::ExIndSubRegNum(bool &valid) {
237 if (base->isRegVar())
238 {
239 short subRegisterOffset = (subRegOff == (short)UNDEFINED_SHORT)? 0: subRegOff;
240 short normSubRegNum = (static_cast<G4_RegVar*>(base)->getPhyRegOff() + subRegisterOffset);
241 MUST_BE_TRUE(normSubRegNum>=0,
242 ERROR_DATA_RANGE("sub-register number"));
243 return ((unsigned short) normSubRegNum);
244 }
245 return ExSubRegNum(valid);
246 }
247
ExIndImmVal(void)248 short G4_DstRegRegion::ExIndImmVal(void) {
249 return immAddrOff;
250 }
251