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