/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- HexagonBitTracker.cpp ----------------------------------------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #include "HexagonBitTracker.h" |
10 | | #include "Hexagon.h" |
11 | | #include "HexagonInstrInfo.h" |
12 | | #include "HexagonRegisterInfo.h" |
13 | | #include "HexagonSubtarget.h" |
14 | | #include "llvm/CodeGen/MachineFrameInfo.h" |
15 | | #include "llvm/CodeGen/MachineFunction.h" |
16 | | #include "llvm/CodeGen/MachineInstr.h" |
17 | | #include "llvm/CodeGen/MachineOperand.h" |
18 | | #include "llvm/CodeGen/MachineRegisterInfo.h" |
19 | | #include "llvm/CodeGen/TargetRegisterInfo.h" |
20 | | #include "llvm/IR/Argument.h" |
21 | | #include "llvm/IR/Attributes.h" |
22 | | #include "llvm/IR/Function.h" |
23 | | #include "llvm/IR/Type.h" |
24 | | #include "llvm/Support/Compiler.h" |
25 | | #include "llvm/Support/Debug.h" |
26 | | #include "llvm/Support/ErrorHandling.h" |
27 | | #include "llvm/Support/MathExtras.h" |
28 | | #include "llvm/Support/raw_ostream.h" |
29 | | #include <cassert> |
30 | | #include <cstddef> |
31 | | #include <cstdint> |
32 | | #include <cstdlib> |
33 | | #include <utility> |
34 | | #include <vector> |
35 | | |
36 | | using namespace llvm; |
37 | | |
38 | | using BT = BitTracker; |
39 | | |
40 | | HexagonEvaluator::HexagonEvaluator(const HexagonRegisterInfo &tri, |
41 | | MachineRegisterInfo &mri, |
42 | | const HexagonInstrInfo &tii, |
43 | | MachineFunction &mf) |
44 | 10.0k | : MachineEvaluator(tri, mri), MF(mf), MFI(mf.getFrameInfo()), TII(tii) { |
45 | 10.0k | // Populate the VRX map (VR to extension-type). |
46 | 10.0k | // Go over all the formal parameters of the function. If a given parameter |
47 | 10.0k | // P is sign- or zero-extended, locate the virtual register holding that |
48 | 10.0k | // parameter and create an entry in the VRX map indicating the type of ex- |
49 | 10.0k | // tension (and the source type). |
50 | 10.0k | // This is a bit complicated to do accurately, since the memory layout in- |
51 | 10.0k | // formation is necessary to precisely determine whether an aggregate para- |
52 | 10.0k | // meter will be passed in a register or in memory. What is given in MRI |
53 | 10.0k | // is the association between the physical register that is live-in (i.e. |
54 | 10.0k | // holds an argument), and the virtual register that this value will be |
55 | 10.0k | // copied into. This, by itself, is not sufficient to map back the virtual |
56 | 10.0k | // register to a formal parameter from Function (since consecutive live-ins |
57 | 10.0k | // from MRI may not correspond to consecutive formal parameters from Func- |
58 | 10.0k | // tion). To avoid the complications with in-memory arguments, only consi- |
59 | 10.0k | // der the initial sequence of formal parameters that are known to be |
60 | 10.0k | // passed via registers. |
61 | 10.0k | unsigned InVirtReg, InPhysReg = 0; |
62 | 10.0k | |
63 | 12.4k | for (const Argument &Arg : MF.getFunction().args()) { |
64 | 12.4k | Type *ATy = Arg.getType(); |
65 | 12.4k | unsigned Width = 0; |
66 | 12.4k | if (ATy->isIntegerTy()) |
67 | 4.60k | Width = ATy->getIntegerBitWidth(); |
68 | 7.83k | else if (ATy->isPointerTy()) |
69 | 2.58k | Width = 32; |
70 | 12.4k | // If pointer size is not set through target data, it will default to |
71 | 12.4k | // Module::AnyPointerSize. |
72 | 12.4k | if (Width == 0 || Width > 647.18k ) |
73 | 5.26k | break; |
74 | 7.18k | if (Arg.hasAttribute(Attribute::ByVal)) |
75 | 27 | continue; |
76 | 7.15k | InPhysReg = getNextPhysReg(InPhysReg, Width); |
77 | 7.15k | if (!InPhysReg) |
78 | 39 | break; |
79 | 7.11k | InVirtReg = getVirtRegFor(InPhysReg); |
80 | 7.11k | if (!InVirtReg) |
81 | 630 | continue; |
82 | 6.48k | if (Arg.hasAttribute(Attribute::SExt)) |
83 | 252 | VRX.insert(std::make_pair(InVirtReg, ExtType(ExtType::SExt, Width))); |
84 | 6.23k | else if (Arg.hasAttribute(Attribute::ZExt)) |
85 | 343 | VRX.insert(std::make_pair(InVirtReg, ExtType(ExtType::ZExt, Width))); |
86 | 6.48k | } |
87 | 10.0k | } |
88 | | |
89 | 34.0k | BT::BitMask HexagonEvaluator::mask(unsigned Reg, unsigned Sub) const { |
90 | 34.0k | if (Sub == 0) |
91 | 0 | return MachineEvaluator::mask(Reg, 0); |
92 | 34.0k | const TargetRegisterClass &RC = *MRI.getRegClass(Reg); |
93 | 34.0k | unsigned ID = RC.getID(); |
94 | 34.0k | uint16_t RW = getRegBitWidth(RegisterRef(Reg, Sub)); |
95 | 34.0k | const auto &HRI = static_cast<const HexagonRegisterInfo&>(TRI); |
96 | 34.0k | bool IsSubLo = (Sub == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_lo)); |
97 | 34.0k | switch (ID) { |
98 | 34.0k | case Hexagon::DoubleRegsRegClassID: |
99 | 34.0k | case Hexagon::HvxWRRegClassID: |
100 | 34.0k | case Hexagon::HvxVQRRegClassID: |
101 | 34.0k | return IsSubLo ? BT::BitMask(0, RW-1)17.6k |
102 | 34.0k | : BT::BitMask(RW, 2*RW-1)16.3k ; |
103 | 34.0k | default: |
104 | 0 | break; |
105 | 0 | } |
106 | | #ifndef NDEBUG |
107 | | dbgs() << printReg(Reg, &TRI, Sub) << " in reg class " |
108 | | << TRI.getRegClassName(&RC) << '\n'; |
109 | | #endif |
110 | 0 | llvm_unreachable("Unexpected register/subregister"); |
111 | 0 | } |
112 | | |
113 | 96.4k | uint16_t HexagonEvaluator::getPhysRegBitWidth(unsigned Reg) const { |
114 | 96.4k | assert(TargetRegisterInfo::isPhysicalRegister(Reg)); |
115 | 96.4k | |
116 | 96.4k | using namespace Hexagon; |
117 | 96.4k | const auto &HST = MF.getSubtarget<HexagonSubtarget>(); |
118 | 96.4k | if (HST.useHVXOps()) { |
119 | 47.2k | for (auto &RC : {HvxVRRegClass, HvxWRRegClass, HvxQRRegClass, |
120 | 47.2k | HvxVQRRegClass}) |
121 | 86.8k | if (RC.contains(Reg)) |
122 | 39.9k | return TRI.getRegSizeInBits(RC); |
123 | 47.2k | } |
124 | 96.4k | // Default treatment for other physical registers. |
125 | 96.4k | if (const TargetRegisterClass *56.5k RC56.5k = TRI.getMinimalPhysRegClass(Reg)) |
126 | 56.5k | return TRI.getRegSizeInBits(*RC); |
127 | 0 | |
128 | 0 | llvm_unreachable( |
129 | 0 | (Twine("Unhandled physical register") + TRI.getName(Reg)).str().c_str()); |
130 | 0 | } |
131 | | |
132 | | const TargetRegisterClass &HexagonEvaluator::composeWithSubRegIndex( |
133 | 835k | const TargetRegisterClass &RC, unsigned Idx) const { |
134 | 835k | if (Idx == 0) |
135 | 767k | return RC; |
136 | 67.7k | |
137 | | #ifndef NDEBUG |
138 | | const auto &HRI = static_cast<const HexagonRegisterInfo&>(TRI); |
139 | | bool IsSubLo = (Idx == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_lo)); |
140 | | bool IsSubHi = (Idx == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_hi)); |
141 | | assert(IsSubLo != IsSubHi && "Must refer to either low or high subreg"); |
142 | | #endif |
143 | | |
144 | 67.7k | switch (RC.getID()) { |
145 | 67.7k | case Hexagon::DoubleRegsRegClassID: |
146 | 14.3k | return Hexagon::IntRegsRegClass; |
147 | 67.7k | case Hexagon::HvxWRRegClassID: |
148 | 53.3k | return Hexagon::HvxVRRegClass; |
149 | 67.7k | case Hexagon::HvxVQRRegClassID: |
150 | 0 | return Hexagon::HvxWRRegClass; |
151 | 67.7k | default: |
152 | 0 | break; |
153 | 0 | } |
154 | | #ifndef NDEBUG |
155 | | dbgs() << "Reg class id: " << RC.getID() << " idx: " << Idx << '\n'; |
156 | | #endif |
157 | 0 | llvm_unreachable("Unimplemented combination of reg class/subreg idx"); |
158 | 0 | } |
159 | | |
160 | | namespace { |
161 | | |
162 | | class RegisterRefs { |
163 | | std::vector<BT::RegisterRef> Vector; |
164 | | |
165 | | public: |
166 | 179k | RegisterRefs(const MachineInstr &MI) : Vector(MI.getNumOperands()) { |
167 | 691k | for (unsigned i = 0, n = Vector.size(); i < n; ++i512k ) { |
168 | 512k | const MachineOperand &MO = MI.getOperand(i); |
169 | 512k | if (MO.isReg()) |
170 | 443k | Vector[i] = BT::RegisterRef(MO); |
171 | 512k | // For indices that don't correspond to registers, the entry will |
172 | 512k | // remain constructed via the default constructor. |
173 | 512k | } |
174 | 179k | } |
175 | | |
176 | 179k | size_t size() const { return Vector.size(); } |
177 | | |
178 | 638k | const BT::RegisterRef &operator[](unsigned n) const { |
179 | 638k | // The main purpose of this operator is to assert with bad argument. |
180 | 638k | assert(n < Vector.size()); |
181 | 638k | return Vector[n]; |
182 | 638k | } |
183 | | }; |
184 | | |
185 | | } // end anonymous namespace |
186 | | |
187 | | bool HexagonEvaluator::evaluate(const MachineInstr &MI, |
188 | | const CellMapType &Inputs, |
189 | 232k | CellMapType &Outputs) const { |
190 | 232k | using namespace Hexagon; |
191 | 232k | |
192 | 232k | unsigned NumDefs = 0; |
193 | 232k | |
194 | 232k | // Sanity verification: there should not be any defs with subregisters. |
195 | 684k | for (const MachineOperand &MO : MI.operands()) { |
196 | 684k | if (!MO.isReg() || !MO.isDef()551k ) |
197 | 454k | continue; |
198 | 229k | NumDefs++; |
199 | 229k | assert(MO.getSubReg() == 0); |
200 | 229k | } |
201 | 232k | |
202 | 232k | if (NumDefs == 0) |
203 | 22.1k | return false; |
204 | 210k | |
205 | 210k | unsigned Opc = MI.getOpcode(); |
206 | 210k | |
207 | 210k | if (MI.mayLoad()) { |
208 | 23.4k | switch (Opc) { |
209 | 23.4k | // These instructions may be marked as mayLoad, but they are generating |
210 | 23.4k | // immediate values, so skip them. |
211 | 23.4k | case CONST32: |
212 | 0 | case CONST64: |
213 | 0 | break; |
214 | 23.4k | default: |
215 | 23.4k | return evaluateLoad(MI, Inputs, Outputs); |
216 | 186k | } |
217 | 186k | } |
218 | 186k | |
219 | 186k | // Check COPY instructions that copy formal parameters into virtual |
220 | 186k | // registers. Such parameters can be sign- or zero-extended at the |
221 | 186k | // call site, and we should take advantage of this knowledge. The MRI |
222 | 186k | // keeps a list of pairs of live-in physical and virtual registers, |
223 | 186k | // which provides information about which virtual registers will hold |
224 | 186k | // the argument values. The function will still contain instructions |
225 | 186k | // defining those virtual registers, and in practice those are COPY |
226 | 186k | // instructions from a physical to a virtual register. In such cases, |
227 | 186k | // applying the argument extension to the virtual register can be seen |
228 | 186k | // as simply mirroring the extension that had already been applied to |
229 | 186k | // the physical register at the call site. If the defining instruction |
230 | 186k | // was not a COPY, it would not be clear how to mirror that extension |
231 | 186k | // on the callee's side. For that reason, only check COPY instructions |
232 | 186k | // for potential extensions. |
233 | 186k | if (MI.isCopy()) { |
234 | 68.5k | if (evaluateFormalCopy(MI, Inputs, Outputs)) |
235 | 849 | return true; |
236 | 186k | } |
237 | 186k | |
238 | 186k | // Beyond this point, if any operand is a global, skip that instruction. |
239 | 186k | // The reason is that certain instructions that can take an immediate |
240 | 186k | // operand can also have a global symbol in that operand. To avoid |
241 | 186k | // checking what kind of operand a given instruction has individually |
242 | 186k | // for each instruction, do it here. Global symbols as operands gene- |
243 | 186k | // rally do not provide any useful information. |
244 | 523k | for (const MachineOperand &MO : MI.operands())186k { |
245 | 523k | if (MO.isGlobal() || MO.isBlockAddress()518k || MO.isSymbol()518k || MO.isJTI()517k || |
246 | 523k | MO.isCPI()517k ) |
247 | 6.82k | return false; |
248 | 523k | } |
249 | 186k | |
250 | 186k | RegisterRefs Reg(MI); |
251 | 179k | #define op(i) MI.getOperand(i)1.39k |
252 | 179k | #define rc(i) RegisterCell::ref(getCell(Reg[i], Inputs))60.0k |
253 | 179k | #define im(i) MI.getOperand(i).getImm()27.7k |
254 | 179k | |
255 | 179k | // If the instruction has no register operands, skip it. |
256 | 179k | if (Reg.size() == 0) |
257 | 0 | return false; |
258 | 179k | |
259 | 179k | // Record result for register in operand 0. |
260 | 179k | auto rr0 = [this,Reg] (const BT::RegisterCell &Val, CellMapType &Outputs) |
261 | 179k | -> bool { |
262 | 46.5k | putCell(Reg[0], Val, Outputs); |
263 | 46.5k | return true; |
264 | 46.5k | }; |
265 | 179k | // Get the cell corresponding to the N-th operand. |
266 | 179k | auto cop = [this, &Reg, &MI, &Inputs](unsigned N, |
267 | 179k | uint16_t W) -> BT::RegisterCell { |
268 | 8.07k | const MachineOperand &Op = MI.getOperand(N); |
269 | 8.07k | if (Op.isImm()) |
270 | 2.79k | return eIMM(Op.getImm(), W); |
271 | 5.28k | if (!Op.isReg()) |
272 | 0 | return RegisterCell::self(0, W); |
273 | 5.28k | assert(getRegBitWidth(Reg[N]) == W && "Register width mismatch"); |
274 | 5.28k | return rc(N); |
275 | 5.28k | }; |
276 | 179k | // Extract RW low bits of the cell. |
277 | 179k | auto lo = [this] (const BT::RegisterCell &RC, uint16_t RW) |
278 | 179k | -> BT::RegisterCell { |
279 | 1.98k | assert(RW <= RC.width()); |
280 | 1.98k | return eXTR(RC, 0, RW); |
281 | 1.98k | }; |
282 | 179k | // Extract RW high bits of the cell. |
283 | 179k | auto hi = [this] (const BT::RegisterCell &RC, uint16_t RW) |
284 | 179k | -> BT::RegisterCell { |
285 | 56 | uint16_t W = RC.width(); |
286 | 56 | assert(RW <= W); |
287 | 56 | return eXTR(RC, W-RW, W); |
288 | 56 | }; |
289 | 179k | // Extract N-th halfword (counting from the least significant position). |
290 | 179k | auto half = [this] (const BT::RegisterCell &RC, unsigned N) |
291 | 179k | -> BT::RegisterCell { |
292 | 696 | assert(N*16+16 <= RC.width()); |
293 | 696 | return eXTR(RC, N*16, N*16+16); |
294 | 696 | }; |
295 | 179k | // Shuffle bits (pick even/odd from cells and merge into result). |
296 | 179k | auto shuffle = [this] (const BT::RegisterCell &Rs, const BT::RegisterCell &Rt, |
297 | 179k | uint16_t BW, bool Odd) -> BT::RegisterCell { |
298 | 32 | uint16_t I = Odd, Ws = Rs.width(); |
299 | 32 | assert(Ws == Rt.width()); |
300 | 32 | RegisterCell RC = eXTR(Rt, I*BW, I*BW+BW).cat(eXTR(Rs, I*BW, I*BW+BW)); |
301 | 32 | I += 2; |
302 | 96 | while (I*BW < Ws) { |
303 | 64 | RC.cat(eXTR(Rt, I*BW, I*BW+BW)).cat(eXTR(Rs, I*BW, I*BW+BW)); |
304 | 64 | I += 2; |
305 | 64 | } |
306 | 32 | return RC; |
307 | 32 | }; |
308 | 179k | |
309 | 179k | // The bitwidth of the 0th operand. In most (if not all) of the |
310 | 179k | // instructions below, the 0th operand is the defined register. |
311 | 179k | // Pre-compute the bitwidth here, because it is needed in many cases |
312 | 179k | // cases below. |
313 | 179k | uint16_t W0 = (Reg[0].Reg != 0) ? getRegBitWidth(Reg[0])173k : 05.35k ; |
314 | 179k | |
315 | 179k | // Register id of the 0th operand. It can be 0. |
316 | 179k | unsigned Reg0 = Reg[0].Reg; |
317 | 179k | |
318 | 179k | switch (Opc) { |
319 | 179k | // Transfer immediate: |
320 | 179k | |
321 | 179k | case A2_tfrsi: |
322 | 9.43k | case A2_tfrpi: |
323 | 9.43k | case CONST32: |
324 | 9.43k | case CONST64: |
325 | 9.43k | return rr0(eIMM(im(1), W0), Outputs); |
326 | 9.43k | case PS_false: |
327 | 61 | return rr0(RegisterCell(W0).fill(0, W0, BT::BitValue::Zero), Outputs); |
328 | 9.43k | case PS_true: |
329 | 29 | return rr0(RegisterCell(W0).fill(0, W0, BT::BitValue::One), Outputs); |
330 | 9.43k | case PS_fi: { |
331 | 696 | int FI = op(1).getIndex(); |
332 | 696 | int Off = op(2).getImm(); |
333 | 696 | unsigned A = MFI.getObjectAlignment(FI) + std::abs(Off); |
334 | 696 | unsigned L = countTrailingZeros(A); |
335 | 696 | RegisterCell RC = RegisterCell::self(Reg[0].Reg, W0); |
336 | 696 | RC.fill(0, L, BT::BitValue::Zero); |
337 | 696 | return rr0(RC, Outputs); |
338 | 9.43k | } |
339 | 9.43k | |
340 | 9.43k | // Transfer register: |
341 | 9.43k | |
342 | 9.43k | case A2_tfr: |
343 | 0 | case A2_tfrp: |
344 | 0 | case C2_pxfer_map: |
345 | 0 | return rr0(rc(1), Outputs); |
346 | 60 | case C2_tfrpr: { |
347 | 60 | uint16_t RW = W0; |
348 | 60 | uint16_t PW = 8; // XXX Pred size: getRegBitWidth(Reg[1]); |
349 | 60 | assert(PW <= RW); |
350 | 60 | RegisterCell PC = eXTR(rc(1), 0, PW); |
351 | 60 | RegisterCell RC = RegisterCell(RW).insert(PC, BT::BitMask(0, PW-1)); |
352 | 60 | RC.fill(PW, RW, BT::BitValue::Zero); |
353 | 60 | return rr0(RC, Outputs); |
354 | 0 | } |
355 | 36 | case C2_tfrrp: { |
356 | 36 | uint16_t RW = W0; |
357 | 36 | uint16_t PW = 8; // XXX Pred size: getRegBitWidth(Reg[1]); |
358 | 36 | RegisterCell RC = RegisterCell::self(Reg[0].Reg, RW); |
359 | 36 | RC.fill(PW, RW, BT::BitValue::Zero); |
360 | 36 | return rr0(eINS(RC, eXTR(rc(1), 0, PW), 0), Outputs); |
361 | 0 | } |
362 | 0 |
|
363 | 0 | // Arithmetic: |
364 | 0 |
|
365 | 72 | case A2_abs: |
366 | 72 | case A2_absp: |
367 | 72 | // TODO |
368 | 72 | break; |
369 | 72 | |
370 | 108 | case A2_addsp: { |
371 | 108 | uint16_t W1 = getRegBitWidth(Reg[1]); |
372 | 108 | assert(W0 == 64 && W1 == 32); |
373 | 108 | RegisterCell CW = RegisterCell(W0).insert(rc(1), BT::BitMask(0, W1-1)); |
374 | 108 | RegisterCell RC = eADD(eSXT(CW, W1), rc(2)); |
375 | 108 | return rr0(RC, Outputs); |
376 | 72 | } |
377 | 3.46k | case A2_add: |
378 | 3.46k | case A2_addp: |
379 | 3.46k | return rr0(eADD(rc(1), rc(2)), Outputs); |
380 | 7.84k | case A2_addi: |
381 | 7.84k | return rr0(eADD(rc(1), eIMM(im(2), W0)), Outputs); |
382 | 3.46k | case S4_addi_asl_ri: { |
383 | 90 | RegisterCell RC = eADD(eIMM(im(1), W0), eASL(rc(2), im(3))); |
384 | 90 | return rr0(RC, Outputs); |
385 | 3.46k | } |
386 | 3.46k | case S4_addi_lsr_ri: { |
387 | 34 | RegisterCell RC = eADD(eIMM(im(1), W0), eLSR(rc(2), im(3))); |
388 | 34 | return rr0(RC, Outputs); |
389 | 3.46k | } |
390 | 3.46k | case S4_addaddi: { |
391 | 202 | RegisterCell RC = eADD(rc(1), eADD(rc(2), eIMM(im(3), W0))); |
392 | 202 | return rr0(RC, Outputs); |
393 | 3.46k | } |
394 | 3.46k | case M4_mpyri_addi: { |
395 | 0 | RegisterCell M = eMLS(rc(2), eIMM(im(3), W0)); |
396 | 0 | RegisterCell RC = eADD(eIMM(im(1), W0), lo(M, W0)); |
397 | 0 | return rr0(RC, Outputs); |
398 | 3.46k | } |
399 | 3.46k | case M4_mpyrr_addi: { |
400 | 48 | RegisterCell M = eMLS(rc(2), rc(3)); |
401 | 48 | RegisterCell RC = eADD(eIMM(im(1), W0), lo(M, W0)); |
402 | 48 | return rr0(RC, Outputs); |
403 | 3.46k | } |
404 | 3.46k | case M4_mpyri_addr_u2: { |
405 | 0 | RegisterCell M = eMLS(eIMM(im(2), W0), rc(3)); |
406 | 0 | RegisterCell RC = eADD(rc(1), lo(M, W0)); |
407 | 0 | return rr0(RC, Outputs); |
408 | 3.46k | } |
409 | 3.46k | case M4_mpyri_addr: { |
410 | 0 | RegisterCell M = eMLS(rc(2), eIMM(im(3), W0)); |
411 | 0 | RegisterCell RC = eADD(rc(1), lo(M, W0)); |
412 | 0 | return rr0(RC, Outputs); |
413 | 3.46k | } |
414 | 3.46k | case M4_mpyrr_addr: { |
415 | 0 | RegisterCell M = eMLS(rc(2), rc(3)); |
416 | 0 | RegisterCell RC = eADD(rc(1), lo(M, W0)); |
417 | 0 | return rr0(RC, Outputs); |
418 | 3.46k | } |
419 | 3.46k | case S4_subaddi: { |
420 | 88 | RegisterCell RC = eADD(rc(1), eSUB(eIMM(im(2), W0), rc(3))); |
421 | 88 | return rr0(RC, Outputs); |
422 | 3.46k | } |
423 | 3.46k | case M2_accii: { |
424 | 0 | RegisterCell RC = eADD(rc(1), eADD(rc(2), eIMM(im(3), W0))); |
425 | 0 | return rr0(RC, Outputs); |
426 | 3.46k | } |
427 | 3.46k | case M2_acci: { |
428 | 252 | RegisterCell RC = eADD(rc(1), eADD(rc(2), rc(3))); |
429 | 252 | return rr0(RC, Outputs); |
430 | 3.46k | } |
431 | 3.46k | case M2_subacc: { |
432 | 0 | RegisterCell RC = eADD(rc(1), eSUB(rc(2), rc(3))); |
433 | 0 | return rr0(RC, Outputs); |
434 | 3.46k | } |
435 | 3.46k | case S2_addasl_rrri: { |
436 | 1.11k | RegisterCell RC = eADD(rc(1), eASL(rc(2), im(3))); |
437 | 1.11k | return rr0(RC, Outputs); |
438 | 3.46k | } |
439 | 3.46k | case C4_addipc: { |
440 | 0 | RegisterCell RPC = RegisterCell::self(Reg[0].Reg, W0); |
441 | 0 | RPC.fill(0, 2, BT::BitValue::Zero); |
442 | 0 | return rr0(eADD(RPC, eIMM(im(2), W0)), Outputs); |
443 | 3.46k | } |
444 | 3.46k | case A2_sub: |
445 | 829 | case A2_subp: |
446 | 829 | return rr0(eSUB(rc(1), rc(2)), Outputs); |
447 | 829 | case A2_subri: |
448 | 389 | return rr0(eSUB(eIMM(im(1), W0), rc(2)), Outputs); |
449 | 829 | case S4_subi_asl_ri: { |
450 | 16 | RegisterCell RC = eSUB(eIMM(im(1), W0), eASL(rc(2), im(3))); |
451 | 16 | return rr0(RC, Outputs); |
452 | 829 | } |
453 | 829 | case S4_subi_lsr_ri: { |
454 | 106 | RegisterCell RC = eSUB(eIMM(im(1), W0), eLSR(rc(2), im(3))); |
455 | 106 | return rr0(RC, Outputs); |
456 | 829 | } |
457 | 829 | case M2_naccii: { |
458 | 0 | RegisterCell RC = eSUB(rc(1), eADD(rc(2), eIMM(im(3), W0))); |
459 | 0 | return rr0(RC, Outputs); |
460 | 829 | } |
461 | 829 | case M2_nacci: { |
462 | 0 | RegisterCell RC = eSUB(rc(1), eADD(rc(2), rc(3))); |
463 | 0 | return rr0(RC, Outputs); |
464 | 829 | } |
465 | 829 | // 32-bit negation is done by "Rd = A2_subri 0, Rs" |
466 | 829 | case A2_negp: |
467 | 16 | return rr0(eSUB(eIMM(0, W0), rc(1)), Outputs); |
468 | 829 | |
469 | 829 | case M2_mpy_up: { |
470 | 56 | RegisterCell M = eMLS(rc(1), rc(2)); |
471 | 56 | return rr0(hi(M, W0), Outputs); |
472 | 829 | } |
473 | 829 | case M2_dpmpyss_s0: |
474 | 204 | return rr0(eMLS(rc(1), rc(2)), Outputs); |
475 | 829 | case M2_dpmpyss_acc_s0: |
476 | 28 | return rr0(eADD(rc(1), eMLS(rc(2), rc(3))), Outputs); |
477 | 829 | case M2_dpmpyss_nac_s0: |
478 | 16 | return rr0(eSUB(rc(1), eMLS(rc(2), rc(3))), Outputs); |
479 | 829 | case M2_mpyi: { |
480 | 611 | RegisterCell M = eMLS(rc(1), rc(2)); |
481 | 611 | return rr0(lo(M, W0), Outputs); |
482 | 829 | } |
483 | 829 | case M2_macsip: { |
484 | 188 | RegisterCell M = eMLS(rc(2), eIMM(im(3), W0)); |
485 | 188 | RegisterCell RC = eADD(rc(1), lo(M, W0)); |
486 | 188 | return rr0(RC, Outputs); |
487 | 829 | } |
488 | 829 | case M2_macsin: { |
489 | 62 | RegisterCell M = eMLS(rc(2), eIMM(im(3), W0)); |
490 | 62 | RegisterCell RC = eSUB(rc(1), lo(M, W0)); |
491 | 62 | return rr0(RC, Outputs); |
492 | 829 | } |
493 | 829 | case M2_maci: { |
494 | 808 | RegisterCell M = eMLS(rc(2), rc(3)); |
495 | 808 | RegisterCell RC = eADD(rc(1), lo(M, W0)); |
496 | 808 | return rr0(RC, Outputs); |
497 | 829 | } |
498 | 829 | case M2_mpysmi: { |
499 | 8 | RegisterCell M = eMLS(rc(1), eIMM(im(2), W0)); |
500 | 8 | return rr0(lo(M, 32), Outputs); |
501 | 829 | } |
502 | 829 | case M2_mpysin: { |
503 | 0 | RegisterCell M = eMLS(rc(1), eIMM(-im(2), W0)); |
504 | 0 | return rr0(lo(M, 32), Outputs); |
505 | 829 | } |
506 | 829 | case M2_mpysip: { |
507 | 262 | RegisterCell M = eMLS(rc(1), eIMM(im(2), W0)); |
508 | 262 | return rr0(lo(M, 32), Outputs); |
509 | 829 | } |
510 | 829 | case M2_mpyu_up: { |
511 | 0 | RegisterCell M = eMLU(rc(1), rc(2)); |
512 | 0 | return rr0(hi(M, W0), Outputs); |
513 | 829 | } |
514 | 829 | case M2_dpmpyuu_s0: |
515 | 240 | return rr0(eMLU(rc(1), rc(2)), Outputs); |
516 | 829 | case M2_dpmpyuu_acc_s0: |
517 | 24 | return rr0(eADD(rc(1), eMLU(rc(2), rc(3))), Outputs); |
518 | 829 | case M2_dpmpyuu_nac_s0: |
519 | 8 | return rr0(eSUB(rc(1), eMLU(rc(2), rc(3))), Outputs); |
520 | 829 | //case M2_mpysu_up: |
521 | 829 | |
522 | 829 | // Logical/bitwise: |
523 | 829 | |
524 | 829 | case A2_andir: |
525 | 528 | return rr0(eAND(rc(1), eIMM(im(2), W0)), Outputs); |
526 | 829 | case A2_and: |
527 | 592 | case A2_andp: |
528 | 592 | return rr0(eAND(rc(1), rc(2)), Outputs); |
529 | 592 | case A4_andn: |
530 | 0 | case A4_andnp: |
531 | 0 | return rr0(eAND(rc(1), eNOT(rc(2))), Outputs); |
532 | 8 | case S4_andi_asl_ri: { |
533 | 8 | RegisterCell RC = eAND(eIMM(im(1), W0), eASL(rc(2), im(3))); |
534 | 8 | return rr0(RC, Outputs); |
535 | 0 | } |
536 | 56 | case S4_andi_lsr_ri: { |
537 | 56 | RegisterCell RC = eAND(eIMM(im(1), W0), eLSR(rc(2), im(3))); |
538 | 56 | return rr0(RC, Outputs); |
539 | 0 | } |
540 | 0 | case M4_and_and: |
541 | 0 | return rr0(eAND(rc(1), eAND(rc(2), rc(3))), Outputs); |
542 | 0 | case M4_and_andn: |
543 | 0 | return rr0(eAND(rc(1), eAND(rc(2), eNOT(rc(3)))), Outputs); |
544 | 0 | case M4_and_or: |
545 | 0 | return rr0(eAND(rc(1), eORL(rc(2), rc(3))), Outputs); |
546 | 0 | case M4_and_xor: |
547 | 0 | return rr0(eAND(rc(1), eXOR(rc(2), rc(3))), Outputs); |
548 | 83 | case A2_orir: |
549 | 83 | return rr0(eORL(rc(1), eIMM(im(2), W0)), Outputs); |
550 | 1.27k | case A2_or: |
551 | 1.27k | case A2_orp: |
552 | 1.27k | return rr0(eORL(rc(1), rc(2)), Outputs); |
553 | 1.27k | case A4_orn: |
554 | 20 | case A4_ornp: |
555 | 20 | return rr0(eORL(rc(1), eNOT(rc(2))), Outputs); |
556 | 60 | case S4_ori_asl_ri: { |
557 | 60 | RegisterCell RC = eORL(eIMM(im(1), W0), eASL(rc(2), im(3))); |
558 | 60 | return rr0(RC, Outputs); |
559 | 20 | } |
560 | 26 | case S4_ori_lsr_ri: { |
561 | 26 | RegisterCell RC = eORL(eIMM(im(1), W0), eLSR(rc(2), im(3))); |
562 | 26 | return rr0(RC, Outputs); |
563 | 20 | } |
564 | 20 | case M4_or_and: |
565 | 0 | return rr0(eORL(rc(1), eAND(rc(2), rc(3))), Outputs); |
566 | 20 | case M4_or_andn: |
567 | 0 | return rr0(eORL(rc(1), eAND(rc(2), eNOT(rc(3)))), Outputs); |
568 | 184 | case S4_or_andi: |
569 | 184 | case S4_or_andix: { |
570 | 184 | RegisterCell RC = eORL(rc(1), eAND(rc(2), eIMM(im(3), W0))); |
571 | 184 | return rr0(RC, Outputs); |
572 | 184 | } |
573 | 184 | case S4_or_ori: { |
574 | 0 | RegisterCell RC = eORL(rc(1), eORL(rc(2), eIMM(im(3), W0))); |
575 | 0 | return rr0(RC, Outputs); |
576 | 184 | } |
577 | 184 | case M4_or_or: |
578 | 32 | return rr0(eORL(rc(1), eORL(rc(2), rc(3))), Outputs); |
579 | 184 | case M4_or_xor: |
580 | 0 | return rr0(eORL(rc(1), eXOR(rc(2), rc(3))), Outputs); |
581 | 300 | case A2_xor: |
582 | 300 | case A2_xorp: |
583 | 300 | return rr0(eXOR(rc(1), rc(2)), Outputs); |
584 | 300 | case M4_xor_and: |
585 | 0 | return rr0(eXOR(rc(1), eAND(rc(2), rc(3))), Outputs); |
586 | 300 | case M4_xor_andn: |
587 | 0 | return rr0(eXOR(rc(1), eAND(rc(2), eNOT(rc(3)))), Outputs); |
588 | 300 | case M4_xor_or: |
589 | 0 | return rr0(eXOR(rc(1), eORL(rc(2), rc(3))), Outputs); |
590 | 300 | case M4_xor_xacc: |
591 | 0 | return rr0(eXOR(rc(1), eXOR(rc(2), rc(3))), Outputs); |
592 | 300 | case A2_not: |
593 | 48 | case A2_notp: |
594 | 48 | return rr0(eNOT(rc(1)), Outputs); |
595 | 48 | |
596 | 828 | case S2_asl_i_r: |
597 | 828 | case S2_asl_i_p: |
598 | 828 | return rr0(eASL(rc(1), im(2)), Outputs); |
599 | 828 | case A2_aslh: |
600 | 74 | return rr0(eASL(rc(1), 16), Outputs); |
601 | 828 | case S2_asl_i_r_acc: |
602 | 0 | case S2_asl_i_p_acc: |
603 | 0 | return rr0(eADD(rc(1), eASL(rc(2), im(3))), Outputs); |
604 | 38 | case S2_asl_i_r_nac: |
605 | 38 | case S2_asl_i_p_nac: |
606 | 38 | return rr0(eSUB(rc(1), eASL(rc(2), im(3))), Outputs); |
607 | 38 | case S2_asl_i_r_and: |
608 | 10 | case S2_asl_i_p_and: |
609 | 10 | return rr0(eAND(rc(1), eASL(rc(2), im(3))), Outputs); |
610 | 1.21k | case S2_asl_i_r_or: |
611 | 1.21k | case S2_asl_i_p_or: |
612 | 1.21k | return rr0(eORL(rc(1), eASL(rc(2), im(3))), Outputs); |
613 | 1.21k | case S2_asl_i_r_xacc: |
614 | 0 | case S2_asl_i_p_xacc: |
615 | 0 | return rr0(eXOR(rc(1), eASL(rc(2), im(3))), Outputs); |
616 | 156 | case S2_asl_i_vh: |
617 | 156 | case S2_asl_i_vw: |
618 | 156 | // TODO |
619 | 156 | break; |
620 | 156 | |
621 | 476 | case S2_asr_i_r: |
622 | 476 | case S2_asr_i_p: |
623 | 476 | return rr0(eASR(rc(1), im(2)), Outputs); |
624 | 476 | case A2_asrh: |
625 | 100 | return rr0(eASR(rc(1), 16), Outputs); |
626 | 476 | case S2_asr_i_r_acc: |
627 | 12 | case S2_asr_i_p_acc: |
628 | 12 | return rr0(eADD(rc(1), eASR(rc(2), im(3))), Outputs); |
629 | 12 | case S2_asr_i_r_nac: |
630 | 0 | case S2_asr_i_p_nac: |
631 | 0 | return rr0(eSUB(rc(1), eASR(rc(2), im(3))), Outputs); |
632 | 8 | case S2_asr_i_r_and: |
633 | 8 | case S2_asr_i_p_and: |
634 | 8 | return rr0(eAND(rc(1), eASR(rc(2), im(3))), Outputs); |
635 | 8 | case S2_asr_i_r_or: |
636 | 0 | case S2_asr_i_p_or: |
637 | 0 | return rr0(eORL(rc(1), eASR(rc(2), im(3))), Outputs); |
638 | 28 | case S2_asr_i_r_rnd: { |
639 | 28 | // The input is first sign-extended to 64 bits, then the output |
640 | 28 | // is truncated back to 32 bits. |
641 | 28 | assert(W0 == 32); |
642 | 28 | RegisterCell XC = eSXT(rc(1).cat(eIMM(0, W0)), W0); |
643 | 28 | RegisterCell RC = eASR(eADD(eASR(XC, im(2)), eIMM(1, 2*W0)), 1); |
644 | 28 | return rr0(eXTR(RC, 0, W0), Outputs); |
645 | 0 | } |
646 | 0 | case S2_asr_i_r_rnd_goodsyntax: { |
647 | 0 | int64_t S = im(2); |
648 | 0 | if (S == 0) |
649 | 0 | return rr0(rc(1), Outputs); |
650 | 0 | // Result: S2_asr_i_r_rnd Rs, u5-1 |
651 | 0 | RegisterCell XC = eSXT(rc(1).cat(eIMM(0, W0)), W0); |
652 | 0 | RegisterCell RC = eLSR(eADD(eASR(XC, S-1), eIMM(1, 2*W0)), 1); |
653 | 0 | return rr0(eXTR(RC, 0, W0), Outputs); |
654 | 0 | } |
655 | 120 | case S2_asr_r_vh: |
656 | 120 | case S2_asr_i_vw: |
657 | 120 | case S2_asr_i_svw_trun: |
658 | 120 | // TODO |
659 | 120 | break; |
660 | 120 | |
661 | 800 | case S2_lsr_i_r: |
662 | 800 | case S2_lsr_i_p: |
663 | 800 | return rr0(eLSR(rc(1), im(2)), Outputs); |
664 | 800 | case S2_lsr_i_r_acc: |
665 | 110 | case S2_lsr_i_p_acc: |
666 | 110 | return rr0(eADD(rc(1), eLSR(rc(2), im(3))), Outputs); |
667 | 110 | case S2_lsr_i_r_nac: |
668 | 0 | case S2_lsr_i_p_nac: |
669 | 0 | return rr0(eSUB(rc(1), eLSR(rc(2), im(3))), Outputs); |
670 | 10 | case S2_lsr_i_r_and: |
671 | 10 | case S2_lsr_i_p_and: |
672 | 10 | return rr0(eAND(rc(1), eLSR(rc(2), im(3))), Outputs); |
673 | 64 | case S2_lsr_i_r_or: |
674 | 64 | case S2_lsr_i_p_or: |
675 | 64 | return rr0(eORL(rc(1), eLSR(rc(2), im(3))), Outputs); |
676 | 64 | case S2_lsr_i_r_xacc: |
677 | 32 | case S2_lsr_i_p_xacc: |
678 | 32 | return rr0(eXOR(rc(1), eLSR(rc(2), im(3))), Outputs); |
679 | 32 | |
680 | 85 | case S2_clrbit_i: { |
681 | 85 | RegisterCell RC = rc(1); |
682 | 85 | RC[im(2)] = BT::BitValue::Zero; |
683 | 85 | return rr0(RC, Outputs); |
684 | 32 | } |
685 | 550 | case S2_setbit_i: { |
686 | 550 | RegisterCell RC = rc(1); |
687 | 550 | RC[im(2)] = BT::BitValue::One; |
688 | 550 | return rr0(RC, Outputs); |
689 | 32 | } |
690 | 142 | case S2_togglebit_i: { |
691 | 142 | RegisterCell RC = rc(1); |
692 | 142 | uint16_t BX = im(2); |
693 | 142 | RC[BX] = RC[BX].is(0) ? BT::BitValue::One0 |
694 | 142 | : RC[BX].is(1) ? BT::BitValue::Zero0 |
695 | 142 | : BT::BitValue::self(); |
696 | 142 | return rr0(RC, Outputs); |
697 | 32 | } |
698 | 32 | |
699 | 32 | case A4_bitspliti: { |
700 | 8 | uint16_t W1 = getRegBitWidth(Reg[1]); |
701 | 8 | uint16_t BX = im(2); |
702 | 8 | // Res.uw[1] = Rs[bx+1:], Res.uw[0] = Rs[0:bx] |
703 | 8 | const BT::BitValue Zero = BT::BitValue::Zero; |
704 | 8 | RegisterCell RZ = RegisterCell(W0).fill(BX, W1, Zero) |
705 | 8 | .fill(W1+(W1-BX), W0, Zero); |
706 | 8 | RegisterCell BF1 = eXTR(rc(1), 0, BX), BF2 = eXTR(rc(1), BX, W1); |
707 | 8 | RegisterCell RC = eINS(eINS(RZ, BF1, 0), BF2, W1); |
708 | 8 | return rr0(RC, Outputs); |
709 | 32 | } |
710 | 803 | case S4_extract: |
711 | 803 | case S4_extractp: |
712 | 803 | case S2_extractu: |
713 | 803 | case S2_extractup: { |
714 | 803 | uint16_t Wd = im(2), Of = im(3); |
715 | 803 | assert(Wd <= W0); |
716 | 803 | if (Wd == 0) |
717 | 12 | return rr0(eIMM(0, W0), Outputs); |
718 | 791 | // If the width extends beyond the register size, pad the register |
719 | 791 | // with 0 bits. |
720 | 791 | RegisterCell Pad = (Wd+Of > W0) ? rc12 (1).cat(eIMM(0, Wd+Of-W0))12 : rc779 (1); |
721 | 791 | RegisterCell Ext = eXTR(Pad, Of, Wd+Of); |
722 | 791 | // Ext is short, need to extend it with 0s or sign bit. |
723 | 791 | RegisterCell RC = RegisterCell(W0).insert(Ext, BT::BitMask(0, Wd-1)); |
724 | 791 | if (Opc == S2_extractu || Opc == S2_extractup500 ) |
725 | 737 | return rr0(eZXT(RC, Wd), Outputs); |
726 | 54 | return rr0(eSXT(RC, Wd), Outputs); |
727 | 54 | } |
728 | 54 | case S2_insert: |
729 | 48 | case S2_insertp: { |
730 | 48 | uint16_t Wd = im(3), Of = im(4); |
731 | 48 | assert(Wd < W0 && Of < W0); |
732 | 48 | // If Wd+Of exceeds W0, the inserted bits are truncated. |
733 | 48 | if (Wd+Of > W0) |
734 | 0 | Wd = W0-Of; |
735 | 48 | if (Wd == 0) |
736 | 0 | return rr0(rc(1), Outputs); |
737 | 48 | return rr0(eINS(rc(1), eXTR(rc(2), 0, Wd), Of), Outputs); |
738 | 48 | } |
739 | 48 | |
740 | 48 | // Bit permutations: |
741 | 48 | |
742 | 655 | case A2_combineii: |
743 | 655 | case A4_combineii: |
744 | 655 | case A4_combineir: |
745 | 655 | case A4_combineri: |
746 | 655 | case A2_combinew: |
747 | 655 | case V6_vcombine: |
748 | 655 | assert(W0 % 2 == 0); |
749 | 655 | return rr0(cop(2, W0/2).cat(cop(1, W0/2)), Outputs); |
750 | 655 | case A2_combine_ll: |
751 | 316 | case A2_combine_lh: |
752 | 316 | case A2_combine_hl: |
753 | 316 | case A2_combine_hh: { |
754 | 316 | assert(W0 == 32); |
755 | 316 | assert(getRegBitWidth(Reg[1]) == 32 && getRegBitWidth(Reg[2]) == 32); |
756 | 316 | // Low half in the output is 0 for _ll and _hl, 1 otherwise: |
757 | 316 | unsigned LoH = !(Opc == A2_combine_ll || Opc == A2_combine_hl6 ); |
758 | 316 | // High half in the output is 0 for _ll and _lh, 1 otherwise: |
759 | 316 | unsigned HiH = !(Opc == A2_combine_ll || Opc == A2_combine_lh6 ); |
760 | 316 | RegisterCell R1 = rc(1); |
761 | 316 | RegisterCell R2 = rc(2); |
762 | 316 | RegisterCell RC = half(R2, LoH).cat(half(R1, HiH)); |
763 | 316 | return rr0(RC, Outputs); |
764 | 316 | } |
765 | 316 | case S2_packhl: { |
766 | 16 | assert(W0 == 64); |
767 | 16 | assert(getRegBitWidth(Reg[1]) == 32 && getRegBitWidth(Reg[2]) == 32); |
768 | 16 | RegisterCell R1 = rc(1); |
769 | 16 | RegisterCell R2 = rc(2); |
770 | 16 | RegisterCell RC = half(R2, 0).cat(half(R1, 0)).cat(half(R2, 1)) |
771 | 16 | .cat(half(R1, 1)); |
772 | 16 | return rr0(RC, Outputs); |
773 | 316 | } |
774 | 316 | case S2_shuffeb: { |
775 | 8 | RegisterCell RC = shuffle(rc(1), rc(2), 8, false); |
776 | 8 | return rr0(RC, Outputs); |
777 | 316 | } |
778 | 316 | case S2_shuffeh: { |
779 | 8 | RegisterCell RC = shuffle(rc(1), rc(2), 16, false); |
780 | 8 | return rr0(RC, Outputs); |
781 | 316 | } |
782 | 316 | case S2_shuffob: { |
783 | 8 | RegisterCell RC = shuffle(rc(1), rc(2), 8, true); |
784 | 8 | return rr0(RC, Outputs); |
785 | 316 | } |
786 | 316 | case S2_shuffoh: { |
787 | 8 | RegisterCell RC = shuffle(rc(1), rc(2), 16, true); |
788 | 8 | return rr0(RC, Outputs); |
789 | 316 | } |
790 | 344 | case C2_mask: { |
791 | 344 | uint16_t WR = W0; |
792 | 344 | uint16_t WP = 8; // XXX Pred size: getRegBitWidth(Reg[1]); |
793 | 344 | assert(WR == 64 && WP == 8); |
794 | 344 | RegisterCell R1 = rc(1); |
795 | 344 | RegisterCell RC(WR); |
796 | 3.09k | for (uint16_t i = 0; i < WP; ++i2.75k ) { |
797 | 2.75k | const BT::BitValue &V = R1[i]; |
798 | 2.75k | BT::BitValue F = (V.is(0) || V.is(1)) ? V0 : BT::BitValue::self(); |
799 | 2.75k | RC.fill(i*8, i*8+8, F); |
800 | 2.75k | } |
801 | 344 | return rr0(RC, Outputs); |
802 | 316 | } |
803 | 316 | |
804 | 316 | // Mux: |
805 | 316 | |
806 | 3.38k | case C2_muxii: |
807 | 3.38k | case C2_muxir: |
808 | 3.38k | case C2_muxri: |
809 | 3.38k | case C2_mux: { |
810 | 3.38k | BT::BitValue PC0 = rc(1)[0]; |
811 | 3.38k | RegisterCell R2 = cop(2, W0); |
812 | 3.38k | RegisterCell R3 = cop(3, W0); |
813 | 3.38k | if (PC0.is(0) || PC0.is(1)3.35k ) |
814 | 42 | return rr0(RegisterCell::ref(PC0 ? R28 : R334 ), Outputs); |
815 | 3.34k | R2.meet(R3, Reg[0].Reg); |
816 | 3.34k | return rr0(R2, Outputs); |
817 | 3.34k | } |
818 | 3.34k | case C2_vmux: |
819 | 92 | // TODO |
820 | 92 | break; |
821 | 3.34k | |
822 | 3.34k | // Sign- and zero-extension: |
823 | 3.34k | |
824 | 3.34k | case A2_sxtb: |
825 | 164 | return rr0(eSXT(rc(1), 8), Outputs); |
826 | 3.34k | case A2_sxth: |
827 | 489 | return rr0(eSXT(rc(1), 16), Outputs); |
828 | 3.34k | case A2_sxtw: { |
829 | 64 | uint16_t W1 = getRegBitWidth(Reg[1]); |
830 | 64 | assert(W0 == 64 && W1 == 32); |
831 | 64 | RegisterCell RC = eSXT(rc(1).cat(eIMM(0, W1)), W1); |
832 | 64 | return rr0(RC, Outputs); |
833 | 3.34k | } |
834 | 3.34k | case A2_zxtb: |
835 | 358 | return rr0(eZXT(rc(1), 8), Outputs); |
836 | 3.34k | case A2_zxth: |
837 | 177 | return rr0(eZXT(rc(1), 16), Outputs); |
838 | 3.34k | |
839 | 3.34k | // Saturations |
840 | 3.34k | |
841 | 3.34k | case A2_satb: |
842 | 10 | return rr0(eSXT(RegisterCell::self(0, W0).regify(Reg0), 8), Outputs); |
843 | 3.34k | case A2_sath: |
844 | 156 | return rr0(eSXT(RegisterCell::self(0, W0).regify(Reg0), 16), Outputs); |
845 | 3.34k | case A2_satub: |
846 | 10 | return rr0(eZXT(RegisterCell::self(0, W0).regify(Reg0), 8), Outputs); |
847 | 3.34k | case A2_satuh: |
848 | 10 | return rr0(eZXT(RegisterCell::self(0, W0).regify(Reg0), 16), Outputs); |
849 | 3.34k | |
850 | 3.34k | // Bit count: |
851 | 3.34k | |
852 | 3.34k | case S2_cl0: |
853 | 92 | case S2_cl0p: |
854 | 92 | // Always produce a 32-bit result. |
855 | 92 | return rr0(eCLB(rc(1), false/*bit*/, 32), Outputs); |
856 | 92 | case S2_cl1: |
857 | 16 | case S2_cl1p: |
858 | 16 | return rr0(eCLB(rc(1), true/*bit*/, 32), Outputs); |
859 | 16 | case S2_clb: |
860 | 10 | case S2_clbp: { |
861 | 10 | uint16_t W1 = getRegBitWidth(Reg[1]); |
862 | 10 | RegisterCell R1 = rc(1); |
863 | 10 | BT::BitValue TV = R1[W1-1]; |
864 | 10 | if (TV.is(0) || TV.is(1)) |
865 | 0 | return rr0(eCLB(R1, TV, 32), Outputs); |
866 | 10 | break; |
867 | 10 | } |
868 | 70 | case S2_ct0: |
869 | 70 | case S2_ct0p: |
870 | 70 | return rr0(eCTB(rc(1), false/*bit*/, 32), Outputs); |
871 | 70 | case S2_ct1: |
872 | 16 | case S2_ct1p: |
873 | 16 | return rr0(eCTB(rc(1), true/*bit*/, 32), Outputs); |
874 | 32 | case S5_popcountp: |
875 | 32 | // TODO |
876 | 32 | break; |
877 | 16 | |
878 | 16 | case C2_all8: { |
879 | 8 | RegisterCell P1 = rc(1); |
880 | 8 | bool Has0 = false, All1 = true; |
881 | 72 | for (uint16_t i = 0; i < 8/*XXX*/; ++i64 ) { |
882 | 64 | if (!P1[i].is(1)) |
883 | 64 | All1 = false; |
884 | 64 | if (!P1[i].is(0)) |
885 | 64 | continue; |
886 | 0 | Has0 = true; |
887 | 0 | break; |
888 | 0 | } |
889 | 8 | if (!Has0 && !All1) |
890 | 8 | break; |
891 | 0 | RegisterCell RC(W0); |
892 | 0 | RC.fill(0, W0, (All1 ? BT::BitValue::One : BT::BitValue::Zero)); |
893 | 0 | return rr0(RC, Outputs); |
894 | 0 | } |
895 | 8 | case C2_any8: { |
896 | 8 | RegisterCell P1 = rc(1); |
897 | 8 | bool Has1 = false, All0 = true; |
898 | 72 | for (uint16_t i = 0; i < 8/*XXX*/; ++i64 ) { |
899 | 64 | if (!P1[i].is(0)) |
900 | 64 | All0 = false; |
901 | 64 | if (!P1[i].is(1)) |
902 | 64 | continue; |
903 | 0 | Has1 = true; |
904 | 0 | break; |
905 | 0 | } |
906 | 8 | if (!Has1 && !All0) |
907 | 8 | break; |
908 | 0 | RegisterCell RC(W0); |
909 | 0 | RC.fill(0, W0, (Has1 ? BT::BitValue::One : BT::BitValue::Zero)); |
910 | 0 | return rr0(RC, Outputs); |
911 | 0 | } |
912 | 50 | case C2_and: |
913 | 50 | return rr0(eAND(rc(1), rc(2)), Outputs); |
914 | 8 | case C2_andn: |
915 | 8 | return rr0(eAND(rc(1), eNOT(rc(2))), Outputs); |
916 | 3.72k | case C2_not: |
917 | 3.72k | return rr0(eNOT(rc(1)), Outputs); |
918 | 60 | case C2_or: |
919 | 60 | return rr0(eORL(rc(1), rc(2)), Outputs); |
920 | 24 | case C2_orn: |
921 | 24 | return rr0(eORL(rc(1), eNOT(rc(2))), Outputs); |
922 | 68 | case C2_xor: |
923 | 68 | return rr0(eXOR(rc(1), rc(2)), Outputs); |
924 | 32 | case C4_and_and: |
925 | 32 | return rr0(eAND(rc(1), eAND(rc(2), rc(3))), Outputs); |
926 | 8 | case C4_and_andn: |
927 | 8 | return rr0(eAND(rc(1), eAND(rc(2), eNOT(rc(3)))), Outputs); |
928 | 8 | case C4_and_or: |
929 | 8 | return rr0(eAND(rc(1), eORL(rc(2), rc(3))), Outputs); |
930 | 8 | case C4_and_orn: |
931 | 8 | return rr0(eAND(rc(1), eORL(rc(2), eNOT(rc(3)))), Outputs); |
932 | 16 | case C4_or_and: |
933 | 16 | return rr0(eORL(rc(1), eAND(rc(2), rc(3))), Outputs); |
934 | 8 | case C4_or_andn: |
935 | 8 | return rr0(eORL(rc(1), eAND(rc(2), eNOT(rc(3)))), Outputs); |
936 | 16 | case C4_or_or: |
937 | 16 | return rr0(eORL(rc(1), eORL(rc(2), rc(3))), Outputs); |
938 | 8 | case C4_or_orn: |
939 | 8 | return rr0(eORL(rc(1), eORL(rc(2), eNOT(rc(3)))), Outputs); |
940 | 139 | case C2_bitsclr: |
941 | 139 | case C2_bitsclri: |
942 | 139 | case C2_bitsset: |
943 | 139 | case C4_nbitsclr: |
944 | 139 | case C4_nbitsclri: |
945 | 139 | case C4_nbitsset: |
946 | 139 | // TODO |
947 | 139 | break; |
948 | 437 | case S2_tstbit_i: |
949 | 437 | case S4_ntstbit_i: { |
950 | 437 | BT::BitValue V = rc(1)[im(2)]; |
951 | 437 | if (V.is(0) || V.is(1)407 ) { |
952 | 30 | // If instruction is S2_tstbit_i, test for 1, otherwise test for 0. |
953 | 30 | bool TV = (Opc == S2_tstbit_i); |
954 | 30 | BT::BitValue F = V.is(TV) ? BT::BitValue::One0 : BT::BitValue::Zero; |
955 | 30 | return rr0(RegisterCell(W0).fill(0, W0, F), Outputs); |
956 | 30 | } |
957 | 407 | break; |
958 | 407 | } |
959 | 407 | |
960 | 131k | default: |
961 | 131k | // For instructions that define a single predicate registers, store |
962 | 131k | // the low 8 bits of the register only. |
963 | 131k | if (unsigned DefR = getUniqueDefVReg(MI)) { |
964 | 98.6k | if (MRI.getRegClass(DefR) == &Hexagon::PredRegsRegClass) { |
965 | 9.36k | BT::RegisterRef PD(DefR, 0); |
966 | 9.36k | uint16_t RW = getRegBitWidth(PD); |
967 | 9.36k | uint16_t PW = 8; // XXX Pred size: getRegBitWidth(Reg[1]); |
968 | 9.36k | RegisterCell RC = RegisterCell::self(DefR, RW); |
969 | 9.36k | RC.fill(PW, RW, BT::BitValue::Zero); |
970 | 9.36k | putCell(PD, RC, Outputs); |
971 | 9.36k | return true; |
972 | 9.36k | } |
973 | 122k | } |
974 | 122k | return MachineEvaluator::evaluate(MI, Inputs, Outputs); |
975 | 1.04k | } |
976 | 1.04k | #undef im |
977 | 1.04k | #undef rc |
978 | 1.04k | #undef op |
979 | 1.04k | return false; |
980 | 1.04k | } |
981 | | |
982 | | bool HexagonEvaluator::evaluate(const MachineInstr &BI, |
983 | | const CellMapType &Inputs, |
984 | | BranchTargetList &Targets, |
985 | 29.1k | bool &FallsThru) const { |
986 | 29.1k | // We need to evaluate one branch at a time. TII::analyzeBranch checks |
987 | 29.1k | // all the branches in a basic block at once, so we cannot use it. |
988 | 29.1k | unsigned Opc = BI.getOpcode(); |
989 | 29.1k | bool SimpleBranch = false; |
990 | 29.1k | bool Negated = false; |
991 | 29.1k | switch (Opc) { |
992 | 29.1k | case Hexagon::J2_jumpf: |
993 | 1.13k | case Hexagon::J2_jumpfpt: |
994 | 1.13k | case Hexagon::J2_jumpfnew: |
995 | 1.13k | case Hexagon::J2_jumpfnewpt: |
996 | 1.13k | Negated = true; |
997 | 1.13k | LLVM_FALLTHROUGH; |
998 | 7.60k | case Hexagon::J2_jumpt: |
999 | 7.60k | case Hexagon::J2_jumptpt: |
1000 | 7.60k | case Hexagon::J2_jumptnew: |
1001 | 7.60k | case Hexagon::J2_jumptnewpt: |
1002 | 7.60k | // Simple branch: if([!]Pn) jump ... |
1003 | 7.60k | // i.e. Op0 = predicate, Op1 = branch target. |
1004 | 7.60k | SimpleBranch = true; |
1005 | 7.60k | break; |
1006 | 8.27k | case Hexagon::J2_jump: |
1007 | 8.27k | Targets.insert(BI.getOperand(0).getMBB()); |
1008 | 8.27k | FallsThru = false; |
1009 | 8.27k | return true; |
1010 | 13.2k | default: |
1011 | 13.2k | // If the branch is of unknown type, assume that all successors are |
1012 | 13.2k | // executable. |
1013 | 13.2k | return false; |
1014 | 7.60k | } |
1015 | 7.60k | |
1016 | 7.60k | if (!SimpleBranch) |
1017 | 0 | return false; |
1018 | 7.60k | |
1019 | 7.60k | // BI is a conditional branch if we got here. |
1020 | 7.60k | RegisterRef PR = BI.getOperand(0); |
1021 | 7.60k | RegisterCell PC = getCell(PR, Inputs); |
1022 | 7.60k | const BT::BitValue &Test = PC[0]; |
1023 | 7.60k | |
1024 | 7.60k | // If the condition is neither true nor false, then it's unknown. |
1025 | 7.60k | if (!Test.is(0) && !Test.is(1)) |
1026 | 7.60k | return false; |
1027 | 0 | |
1028 | 0 | // "Test.is(!Negated)" means "branch condition is true". |
1029 | 0 | if (!Test.is(!Negated)) { |
1030 | 0 | // Condition known to be false. |
1031 | 0 | FallsThru = true; |
1032 | 0 | return true; |
1033 | 0 | } |
1034 | 0 | |
1035 | 0 | Targets.insert(BI.getOperand(1).getMBB()); |
1036 | 0 | FallsThru = false; |
1037 | 0 | return true; |
1038 | 0 | } |
1039 | | |
1040 | 131k | unsigned HexagonEvaluator::getUniqueDefVReg(const MachineInstr &MI) const { |
1041 | 131k | unsigned DefReg = 0; |
1042 | 375k | for (const MachineOperand &Op : MI.operands()) { |
1043 | 375k | if (!Op.isReg() || !Op.isDef()338k ) |
1044 | 234k | continue; |
1045 | 141k | unsigned R = Op.getReg(); |
1046 | 141k | if (!TargetRegisterInfo::isVirtualRegister(R)) |
1047 | 42.2k | continue; |
1048 | 98.8k | if (DefReg != 0) |
1049 | 64 | return 0; |
1050 | 98.7k | DefReg = R; |
1051 | 98.7k | } |
1052 | 131k | return DefReg131k ; |
1053 | 131k | } |
1054 | | |
1055 | | bool HexagonEvaluator::evaluateLoad(const MachineInstr &MI, |
1056 | | const CellMapType &Inputs, |
1057 | 23.4k | CellMapType &Outputs) const { |
1058 | 23.4k | using namespace Hexagon; |
1059 | 23.4k | |
1060 | 23.4k | if (TII.isPredicated(MI)) |
1061 | 0 | return false; |
1062 | 23.4k | assert(MI.mayLoad() && "A load that mayn't?"); |
1063 | 23.4k | unsigned Opc = MI.getOpcode(); |
1064 | 23.4k | |
1065 | 23.4k | uint16_t BitNum; |
1066 | 23.4k | bool SignEx; |
1067 | 23.4k | |
1068 | 23.4k | switch (Opc) { |
1069 | 23.4k | default: |
1070 | 11.4k | return false; |
1071 | 23.4k | |
1072 | | #if 0 |
1073 | | // memb_fifo |
1074 | | case L2_loadalignb_pbr: |
1075 | | case L2_loadalignb_pcr: |
1076 | | case L2_loadalignb_pi: |
1077 | | // memh_fifo |
1078 | | case L2_loadalignh_pbr: |
1079 | | case L2_loadalignh_pcr: |
1080 | | case L2_loadalignh_pi: |
1081 | | // membh |
1082 | | case L2_loadbsw2_pbr: |
1083 | | case L2_loadbsw2_pci: |
1084 | | case L2_loadbsw2_pcr: |
1085 | | case L2_loadbsw2_pi: |
1086 | | case L2_loadbsw4_pbr: |
1087 | | case L2_loadbsw4_pci: |
1088 | | case L2_loadbsw4_pcr: |
1089 | | case L2_loadbsw4_pi: |
1090 | | // memubh |
1091 | | case L2_loadbzw2_pbr: |
1092 | | case L2_loadbzw2_pci: |
1093 | | case L2_loadbzw2_pcr: |
1094 | | case L2_loadbzw2_pi: |
1095 | | case L2_loadbzw4_pbr: |
1096 | | case L2_loadbzw4_pci: |
1097 | | case L2_loadbzw4_pcr: |
1098 | | case L2_loadbzw4_pi: |
1099 | | #endif |
1100 | | |
1101 | 23.4k | case L2_loadrbgp: |
1102 | 325 | case L2_loadrb_io: |
1103 | 325 | case L2_loadrb_pbr: |
1104 | 325 | case L2_loadrb_pci: |
1105 | 325 | case L2_loadrb_pcr: |
1106 | 325 | case L2_loadrb_pi: |
1107 | 325 | case PS_loadrbabs: |
1108 | 325 | case L4_loadrb_ap: |
1109 | 325 | case L4_loadrb_rr: |
1110 | 325 | case L4_loadrb_ur: |
1111 | 325 | BitNum = 8; |
1112 | 325 | SignEx = true; |
1113 | 325 | break; |
1114 | 325 | |
1115 | 1.77k | case L2_loadrubgp: |
1116 | 1.77k | case L2_loadrub_io: |
1117 | 1.77k | case L2_loadrub_pbr: |
1118 | 1.77k | case L2_loadrub_pci: |
1119 | 1.77k | case L2_loadrub_pcr: |
1120 | 1.77k | case L2_loadrub_pi: |
1121 | 1.77k | case PS_loadrubabs: |
1122 | 1.77k | case L4_loadrub_ap: |
1123 | 1.77k | case L4_loadrub_rr: |
1124 | 1.77k | case L4_loadrub_ur: |
1125 | 1.77k | BitNum = 8; |
1126 | 1.77k | SignEx = false; |
1127 | 1.77k | break; |
1128 | 1.77k | |
1129 | 1.77k | case L2_loadrhgp: |
1130 | 395 | case L2_loadrh_io: |
1131 | 395 | case L2_loadrh_pbr: |
1132 | 395 | case L2_loadrh_pci: |
1133 | 395 | case L2_loadrh_pcr: |
1134 | 395 | case L2_loadrh_pi: |
1135 | 395 | case PS_loadrhabs: |
1136 | 395 | case L4_loadrh_ap: |
1137 | 395 | case L4_loadrh_rr: |
1138 | 395 | case L4_loadrh_ur: |
1139 | 395 | BitNum = 16; |
1140 | 395 | SignEx = true; |
1141 | 395 | break; |
1142 | 395 | |
1143 | 680 | case L2_loadruhgp: |
1144 | 680 | case L2_loadruh_io: |
1145 | 680 | case L2_loadruh_pbr: |
1146 | 680 | case L2_loadruh_pci: |
1147 | 680 | case L2_loadruh_pcr: |
1148 | 680 | case L2_loadruh_pi: |
1149 | 680 | case L4_loadruh_rr: |
1150 | 680 | case PS_loadruhabs: |
1151 | 680 | case L4_loadruh_ap: |
1152 | 680 | case L4_loadruh_ur: |
1153 | 680 | BitNum = 16; |
1154 | 680 | SignEx = false; |
1155 | 680 | break; |
1156 | 680 | |
1157 | 6.35k | case L2_loadrigp: |
1158 | 6.35k | case L2_loadri_io: |
1159 | 6.35k | case L2_loadri_pbr: |
1160 | 6.35k | case L2_loadri_pci: |
1161 | 6.35k | case L2_loadri_pcr: |
1162 | 6.35k | case L2_loadri_pi: |
1163 | 6.35k | case L2_loadw_locked: |
1164 | 6.35k | case PS_loadriabs: |
1165 | 6.35k | case L4_loadri_ap: |
1166 | 6.35k | case L4_loadri_rr: |
1167 | 6.35k | case L4_loadri_ur: |
1168 | 6.35k | case LDriw_pred: |
1169 | 6.35k | BitNum = 32; |
1170 | 6.35k | SignEx = true; |
1171 | 6.35k | break; |
1172 | 6.35k | |
1173 | 6.35k | case L2_loadrdgp: |
1174 | 2.45k | case L2_loadrd_io: |
1175 | 2.45k | case L2_loadrd_pbr: |
1176 | 2.45k | case L2_loadrd_pci: |
1177 | 2.45k | case L2_loadrd_pcr: |
1178 | 2.45k | case L2_loadrd_pi: |
1179 | 2.45k | case L4_loadd_locked: |
1180 | 2.45k | case PS_loadrdabs: |
1181 | 2.45k | case L4_loadrd_ap: |
1182 | 2.45k | case L4_loadrd_rr: |
1183 | 2.45k | case L4_loadrd_ur: |
1184 | 2.45k | BitNum = 64; |
1185 | 2.45k | SignEx = true; |
1186 | 2.45k | break; |
1187 | 11.9k | } |
1188 | 11.9k | |
1189 | 11.9k | const MachineOperand &MD = MI.getOperand(0); |
1190 | 11.9k | assert(MD.isReg() && MD.isDef()); |
1191 | 11.9k | RegisterRef RD = MD; |
1192 | 11.9k | |
1193 | 11.9k | uint16_t W = getRegBitWidth(RD); |
1194 | 11.9k | assert(W >= BitNum && BitNum > 0); |
1195 | 11.9k | RegisterCell Res(W); |
1196 | 11.9k | |
1197 | 406k | for (uint16_t i = 0; i < BitNum; ++i394k ) |
1198 | 394k | Res[i] = BT::BitValue::self(BT::BitRef(RD.Reg, i)); |
1199 | 11.9k | |
1200 | 11.9k | if (SignEx) { |
1201 | 9.52k | const BT::BitValue &Sign = Res[BitNum-1]; |
1202 | 23.6k | for (uint16_t i = BitNum; i < W; ++i14.1k ) |
1203 | 14.1k | Res[i] = BT::BitValue::ref(Sign); |
1204 | 9.52k | } else { |
1205 | 55.9k | for (uint16_t i = BitNum; i < W; ++i53.4k ) |
1206 | 53.4k | Res[i] = BT::BitValue::Zero; |
1207 | 2.45k | } |
1208 | 11.9k | |
1209 | 11.9k | putCell(RD, Res, Outputs); |
1210 | 11.9k | return true; |
1211 | 11.9k | } |
1212 | | |
1213 | | bool HexagonEvaluator::evaluateFormalCopy(const MachineInstr &MI, |
1214 | | const CellMapType &Inputs, |
1215 | 68.5k | CellMapType &Outputs) const { |
1216 | 68.5k | // If MI defines a formal parameter, but is not a copy (loads are handled |
1217 | 68.5k | // in evaluateLoad), then it's not clear what to do. |
1218 | 68.5k | assert(MI.isCopy()); |
1219 | 68.5k | |
1220 | 68.5k | RegisterRef RD = MI.getOperand(0); |
1221 | 68.5k | RegisterRef RS = MI.getOperand(1); |
1222 | 68.5k | assert(RD.Sub == 0); |
1223 | 68.5k | if (!TargetRegisterInfo::isPhysicalRegister(RS.Reg)) |
1224 | 47.3k | return false; |
1225 | 21.1k | RegExtMap::const_iterator F = VRX.find(RD.Reg); |
1226 | 21.1k | if (F == VRX.end()) |
1227 | 20.3k | return false; |
1228 | 849 | |
1229 | 849 | uint16_t EW = F->second.Width; |
1230 | 849 | // Store RD's cell into the map. This will associate the cell with a virtual |
1231 | 849 | // register, and make zero-/sign-extends possible (otherwise we would be ex- |
1232 | 849 | // tending "self" bit values, which will have no effect, since "self" values |
1233 | 849 | // cannot be references to anything). |
1234 | 849 | putCell(RD, getCell(RS, Inputs), Outputs); |
1235 | 849 | |
1236 | 849 | RegisterCell Res; |
1237 | 849 | // Read RD's cell from the outputs instead of RS's cell from the inputs: |
1238 | 849 | if (F->second.Type == ExtType::SExt) |
1239 | 362 | Res = eSXT(getCell(RD, Outputs), EW); |
1240 | 487 | else if (F->second.Type == ExtType::ZExt) |
1241 | 487 | Res = eZXT(getCell(RD, Outputs), EW); |
1242 | 849 | |
1243 | 849 | putCell(RD, Res, Outputs); |
1244 | 849 | return true; |
1245 | 849 | } |
1246 | | |
1247 | 7.15k | unsigned HexagonEvaluator::getNextPhysReg(unsigned PReg, unsigned Width) const { |
1248 | 7.15k | using namespace Hexagon; |
1249 | 7.15k | |
1250 | 7.15k | bool Is64 = DoubleRegsRegClass.contains(PReg); |
1251 | 7.15k | assert(PReg == 0 || Is64 || IntRegsRegClass.contains(PReg)); |
1252 | 7.15k | |
1253 | 7.15k | static const unsigned Phys32[] = { R0, R1, R2, R3, R4, R5 }; |
1254 | 7.15k | static const unsigned Phys64[] = { D0, D1, D2 }; |
1255 | 7.15k | const unsigned Num32 = sizeof(Phys32)/sizeof(unsigned); |
1256 | 7.15k | const unsigned Num64 = sizeof(Phys64)/sizeof(unsigned); |
1257 | 7.15k | |
1258 | 7.15k | // Return the first parameter register of the required width. |
1259 | 7.15k | if (PReg == 0) |
1260 | 3.50k | return (Width <= 32) ? Phys32[0]3.12k : Phys64[0]376 ; |
1261 | 3.65k | |
1262 | 3.65k | // Set Idx32, Idx64 in such a way that Idx+1 would give the index of the |
1263 | 3.65k | // next register. |
1264 | 3.65k | unsigned Idx32 = 0, Idx64 = 0; |
1265 | 3.65k | if (!Is64) { |
1266 | 5.75k | while (Idx32 < Num32) { |
1267 | 5.75k | if (Phys32[Idx32] == PReg) |
1268 | 3.37k | break; |
1269 | 2.38k | Idx32++; |
1270 | 2.38k | } |
1271 | 3.37k | Idx64 = Idx32/2; |
1272 | 3.37k | } else { |
1273 | 333 | while (Idx64 < Num64) { |
1274 | 333 | if (Phys64[Idx64] == PReg) |
1275 | 282 | break; |
1276 | 51 | Idx64++; |
1277 | 51 | } |
1278 | 282 | Idx32 = Idx64*2+1; |
1279 | 282 | } |
1280 | 3.65k | |
1281 | 3.65k | if (Width <= 32) |
1282 | 3.37k | return (Idx32+1 < Num32) ? Phys32[Idx32+1]3.34k : 039 ; |
1283 | 273 | return (Idx64+1 < Num64) ? Phys64[Idx64+1] : 00 ; |
1284 | 273 | } |
1285 | | |
1286 | 7.11k | unsigned HexagonEvaluator::getVirtRegFor(unsigned PReg) const { |
1287 | 7.11k | for (std::pair<unsigned,unsigned> P : MRI.liveins()) |
1288 | 12.0k | if (P.first == PReg) |
1289 | 6.48k | return P.second; |
1290 | 7.11k | return 0630 ; |
1291 | 7.11k | } |