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