LLVM  3.7.0
HexagonMCCompound.cpp
Go to the documentation of this file.
1 
2 //=== HexagonMCCompound.cpp - Hexagon Compound checker -------===//
3 //
4 // The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // This file is looks at a packet and tries to form compound insns
12 //
13 //===----------------------------------------------------------------------===//
14 #include "Hexagon.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/MC/MCAssembler.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCSectionELF.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/MCSymbol.h"
24 #include "llvm/Support/Debug.h"
26 
27 using namespace llvm;
28 using namespace Hexagon;
29 
30 #define DEBUG_TYPE "hexagon-mccompound"
31 
41 };
42 
43 static const unsigned tstBitOpcode[8] = {
44  J4_tstbit0_fp0_jump_nt, J4_tstbit0_fp0_jump_t, J4_tstbit0_fp1_jump_nt,
45  J4_tstbit0_fp1_jump_t, J4_tstbit0_tp0_jump_nt, J4_tstbit0_tp0_jump_t,
46  J4_tstbit0_tp1_jump_nt, J4_tstbit0_tp1_jump_t};
47 static const unsigned cmpeqBitOpcode[8] = {
48  J4_cmpeq_fp0_jump_nt, J4_cmpeq_fp0_jump_t, J4_cmpeq_fp1_jump_nt,
49  J4_cmpeq_fp1_jump_t, J4_cmpeq_tp0_jump_nt, J4_cmpeq_tp0_jump_t,
50  J4_cmpeq_tp1_jump_nt, J4_cmpeq_tp1_jump_t};
51 static const unsigned cmpgtBitOpcode[8] = {
52  J4_cmpgt_fp0_jump_nt, J4_cmpgt_fp0_jump_t, J4_cmpgt_fp1_jump_nt,
53  J4_cmpgt_fp1_jump_t, J4_cmpgt_tp0_jump_nt, J4_cmpgt_tp0_jump_t,
54  J4_cmpgt_tp1_jump_nt, J4_cmpgt_tp1_jump_t};
55 static const unsigned cmpgtuBitOpcode[8] = {
56  J4_cmpgtu_fp0_jump_nt, J4_cmpgtu_fp0_jump_t, J4_cmpgtu_fp1_jump_nt,
57  J4_cmpgtu_fp1_jump_t, J4_cmpgtu_tp0_jump_nt, J4_cmpgtu_tp0_jump_t,
58  J4_cmpgtu_tp1_jump_nt, J4_cmpgtu_tp1_jump_t};
59 static const unsigned cmpeqiBitOpcode[8] = {
60  J4_cmpeqi_fp0_jump_nt, J4_cmpeqi_fp0_jump_t, J4_cmpeqi_fp1_jump_nt,
61  J4_cmpeqi_fp1_jump_t, J4_cmpeqi_tp0_jump_nt, J4_cmpeqi_tp0_jump_t,
62  J4_cmpeqi_tp1_jump_nt, J4_cmpeqi_tp1_jump_t};
63 static const unsigned cmpgtiBitOpcode[8] = {
64  J4_cmpgti_fp0_jump_nt, J4_cmpgti_fp0_jump_t, J4_cmpgti_fp1_jump_nt,
65  J4_cmpgti_fp1_jump_t, J4_cmpgti_tp0_jump_nt, J4_cmpgti_tp0_jump_t,
66  J4_cmpgti_tp1_jump_nt, J4_cmpgti_tp1_jump_t};
67 static const unsigned cmpgtuiBitOpcode[8] = {
68  J4_cmpgtui_fp0_jump_nt, J4_cmpgtui_fp0_jump_t, J4_cmpgtui_fp1_jump_nt,
69  J4_cmpgtui_fp1_jump_t, J4_cmpgtui_tp0_jump_nt, J4_cmpgtui_tp0_jump_t,
70  J4_cmpgtui_tp1_jump_nt, J4_cmpgtui_tp1_jump_t};
71 static const unsigned cmpeqn1BitOpcode[8] = {
72  J4_cmpeqn1_fp0_jump_nt, J4_cmpeqn1_fp0_jump_t, J4_cmpeqn1_fp1_jump_nt,
73  J4_cmpeqn1_fp1_jump_t, J4_cmpeqn1_tp0_jump_nt, J4_cmpeqn1_tp0_jump_t,
74  J4_cmpeqn1_tp1_jump_nt, J4_cmpeqn1_tp1_jump_t};
75 static const unsigned cmpgtn1BitOpcode[8] = {
76  J4_cmpgtn1_fp0_jump_nt, J4_cmpgtn1_fp0_jump_t, J4_cmpgtn1_fp1_jump_nt,
77  J4_cmpgtn1_fp1_jump_t, J4_cmpgtn1_tp0_jump_nt, J4_cmpgtn1_tp0_jump_t,
78  J4_cmpgtn1_tp1_jump_nt, J4_cmpgtn1_tp1_jump_t,
79 };
80 
81 // enum HexagonII::CompoundGroup
82 namespace {
83 unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) {
84  unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
85 
86  switch (MI.getOpcode()) {
87  default:
88  return HexagonII::HCG_None;
89  //
90  // Compound pairs.
91  // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
92  // "Rd16=#U6 ; jump #r9:2"
93  // "Rd16=Rs16 ; jump #r9:2"
94  //
95  case Hexagon::C2_cmpeq:
96  case Hexagon::C2_cmpgt:
97  case Hexagon::C2_cmpgtu:
98  if (IsExtended)
99  return false;
100  DstReg = MI.getOperand(0).getReg();
101  Src1Reg = MI.getOperand(1).getReg();
102  Src2Reg = MI.getOperand(2).getReg();
103  if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
106  return HexagonII::HCG_A;
107  break;
108  case Hexagon::C2_cmpeqi:
109  case Hexagon::C2_cmpgti:
110  case Hexagon::C2_cmpgtui:
111  if (IsExtended)
112  return false;
113  // P0 = cmp.eq(Rs,#u2)
114  DstReg = MI.getOperand(0).getReg();
115  SrcReg = MI.getOperand(1).getReg();
116  if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
118  MI.getOperand(2).isImm() && ((isUInt<5>(MI.getOperand(2).getImm())) ||
119  (MI.getOperand(2).getImm() == -1)))
120  return HexagonII::HCG_A;
121  break;
122  case Hexagon::A2_tfr:
123  if (IsExtended)
124  return false;
125  // Rd = Rs
126  DstReg = MI.getOperand(0).getReg();
127  SrcReg = MI.getOperand(1).getReg();
130  return HexagonII::HCG_A;
131  break;
132  case Hexagon::A2_tfrsi:
133  if (IsExtended)
134  return false;
135  // Rd = #u6
136  DstReg = MI.getOperand(0).getReg();
137  if (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() <= 63 &&
138  MI.getOperand(1).getImm() >= 0 &&
140  return HexagonII::HCG_A;
141  break;
142  case Hexagon::S2_tstbit_i:
143  if (IsExtended)
144  return false;
145  DstReg = MI.getOperand(0).getReg();
146  Src1Reg = MI.getOperand(1).getReg();
147  if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
148  MI.getOperand(2).isImm() &&
150  (MI.getOperand(2).getImm() == 0))
151  return HexagonII::HCG_A;
152  break;
153  // The fact that .new form is used pretty much guarantees
154  // that predicate register will match. Nevertheless,
155  // there could be some false positives without additional
156  // checking.
157  case Hexagon::J2_jumptnew:
158  case Hexagon::J2_jumpfnew:
159  case Hexagon::J2_jumptnewpt:
160  case Hexagon::J2_jumpfnewpt:
161  Src1Reg = MI.getOperand(0).getReg();
162  if (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg)
163  return HexagonII::HCG_B;
164  break;
165  // Transfer and jump:
166  // Rd=#U6 ; jump #r9:2
167  // Rd=Rs ; jump #r9:2
168  // Do not test for jump range here.
169  case Hexagon::J2_jump:
170  case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
171  return HexagonII::HCG_C;
172  break;
173  }
174 
175  return HexagonII::HCG_None;
176 }
177 }
178 
179 /// getCompoundOp - Return the index from 0-7 into the above opcode lists.
180 namespace {
181 unsigned getCompoundOp(MCInst const &HMCI) {
182  const MCOperand &Predicate = HMCI.getOperand(0);
183  unsigned PredReg = Predicate.getReg();
184 
185  assert((PredReg == Hexagon::P0) || (PredReg == Hexagon::P1) ||
186  (PredReg == Hexagon::P2) || (PredReg == Hexagon::P3));
187 
188  switch (HMCI.getOpcode()) {
189  default:
190  llvm_unreachable("Expected match not found.\n");
191  break;
192  case Hexagon::J2_jumpfnew:
193  return (PredReg == Hexagon::P0) ? fp0_jump_nt : fp1_jump_nt;
194  case Hexagon::J2_jumpfnewpt:
195  return (PredReg == Hexagon::P0) ? fp0_jump_t : fp1_jump_t;
196  case Hexagon::J2_jumptnew:
197  return (PredReg == Hexagon::P0) ? tp0_jump_nt : tp1_jump_nt;
198  case Hexagon::J2_jumptnewpt:
199  return (PredReg == Hexagon::P0) ? tp0_jump_t : tp1_jump_t;
200  }
201 }
202 }
203 
204 namespace {
205 MCInst *getCompoundInsn(MCContext &Context, MCInst const &L, MCInst const &R) {
206  MCInst *CompoundInsn = 0;
207  unsigned compoundOpcode;
208  MCOperand Rs, Rt;
209 
210  switch (L.getOpcode()) {
211  default:
212  DEBUG(dbgs() << "Possible compound ignored\n");
213  return CompoundInsn;
214 
215  case Hexagon::A2_tfrsi:
216  Rt = L.getOperand(0);
217  compoundOpcode = J4_jumpseti;
218  CompoundInsn = new (Context) MCInst;
219  CompoundInsn->setOpcode(compoundOpcode);
220 
221  CompoundInsn->addOperand(Rt);
222  CompoundInsn->addOperand(L.getOperand(1)); // Immediate
223  CompoundInsn->addOperand(R.getOperand(0)); // Jump target
224  break;
225 
226  case Hexagon::A2_tfr:
227  Rt = L.getOperand(0);
228  Rs = L.getOperand(1);
229 
230  compoundOpcode = J4_jumpsetr;
231  CompoundInsn = new (Context) MCInst;
232  CompoundInsn->setOpcode(compoundOpcode);
233  CompoundInsn->addOperand(Rt);
234  CompoundInsn->addOperand(Rs);
235  CompoundInsn->addOperand(R.getOperand(0)); // Jump target.
236 
237  break;
238 
239  case Hexagon::C2_cmpeq:
240  DEBUG(dbgs() << "CX: C2_cmpeq\n");
241  Rs = L.getOperand(1);
242  Rt = L.getOperand(2);
243 
244  compoundOpcode = cmpeqBitOpcode[getCompoundOp(R)];
245  CompoundInsn = new (Context) MCInst;
246  CompoundInsn->setOpcode(compoundOpcode);
247  CompoundInsn->addOperand(Rs);
248  CompoundInsn->addOperand(Rt);
249  CompoundInsn->addOperand(R.getOperand(1));
250  break;
251 
252  case Hexagon::C2_cmpgt:
253  DEBUG(dbgs() << "CX: C2_cmpgt\n");
254  Rs = L.getOperand(1);
255  Rt = L.getOperand(2);
256 
257  compoundOpcode = cmpgtBitOpcode[getCompoundOp(R)];
258  CompoundInsn = new (Context) MCInst;
259  CompoundInsn->setOpcode(compoundOpcode);
260  CompoundInsn->addOperand(Rs);
261  CompoundInsn->addOperand(Rt);
262  CompoundInsn->addOperand(R.getOperand(1));
263  break;
264 
265  case Hexagon::C2_cmpgtu:
266  DEBUG(dbgs() << "CX: C2_cmpgtu\n");
267  Rs = L.getOperand(1);
268  Rt = L.getOperand(2);
269 
270  compoundOpcode = cmpgtuBitOpcode[getCompoundOp(R)];
271  CompoundInsn = new (Context) MCInst;
272  CompoundInsn->setOpcode(compoundOpcode);
273  CompoundInsn->addOperand(Rs);
274  CompoundInsn->addOperand(Rt);
275  CompoundInsn->addOperand(R.getOperand(1));
276  break;
277 
278  case Hexagon::C2_cmpeqi:
279  DEBUG(dbgs() << "CX: C2_cmpeqi\n");
280  if (L.getOperand(2).getImm() == -1)
281  compoundOpcode = cmpeqn1BitOpcode[getCompoundOp(R)];
282  else
283  compoundOpcode = cmpeqiBitOpcode[getCompoundOp(R)];
284 
285  Rs = L.getOperand(1);
286  CompoundInsn = new (Context) MCInst;
287  CompoundInsn->setOpcode(compoundOpcode);
288  CompoundInsn->addOperand(Rs);
289  if (L.getOperand(2).getImm() != -1)
290  CompoundInsn->addOperand(L.getOperand(2));
291  CompoundInsn->addOperand(R.getOperand(1));
292  break;
293 
294  case Hexagon::C2_cmpgti:
295  DEBUG(dbgs() << "CX: C2_cmpgti\n");
296  if (L.getOperand(2).getImm() == -1)
297  compoundOpcode = cmpgtn1BitOpcode[getCompoundOp(R)];
298  else
299  compoundOpcode = cmpgtiBitOpcode[getCompoundOp(R)];
300 
301  Rs = L.getOperand(1);
302  CompoundInsn = new (Context) MCInst;
303  CompoundInsn->setOpcode(compoundOpcode);
304  CompoundInsn->addOperand(Rs);
305  if (L.getOperand(2).getImm() != -1)
306  CompoundInsn->addOperand(L.getOperand(2));
307  CompoundInsn->addOperand(R.getOperand(1));
308  break;
309 
310  case Hexagon::C2_cmpgtui:
311  DEBUG(dbgs() << "CX: C2_cmpgtui\n");
312  Rs = L.getOperand(1);
313  compoundOpcode = cmpgtuiBitOpcode[getCompoundOp(R)];
314  CompoundInsn = new (Context) MCInst;
315  CompoundInsn->setOpcode(compoundOpcode);
316  CompoundInsn->addOperand(Rs);
317  CompoundInsn->addOperand(L.getOperand(2));
318  CompoundInsn->addOperand(R.getOperand(1));
319  break;
320 
321  case Hexagon::S2_tstbit_i:
322  DEBUG(dbgs() << "CX: S2_tstbit_i\n");
323  Rs = L.getOperand(1);
324  compoundOpcode = tstBitOpcode[getCompoundOp(R)];
325  CompoundInsn = new (Context) MCInst;
326  CompoundInsn->setOpcode(compoundOpcode);
327  CompoundInsn->addOperand(Rs);
328  CompoundInsn->addOperand(R.getOperand(1));
329  break;
330  }
331 
332  return CompoundInsn;
333 }
334 }
335 
336 /// Non-Symmetrical. See if these two instructions are fit for compound pair.
337 namespace {
338 bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA,
339  MCInst const &MIb, bool IsExtendedB) {
340  unsigned MIaG = getCompoundCandidateGroup(MIa, IsExtendedA);
341  unsigned MIbG = getCompoundCandidateGroup(MIb, IsExtendedB);
342  // We have two candidates - check that this is the same register
343  // we are talking about.
344  unsigned Opca = MIa.getOpcode();
345  if (MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_C &&
346  (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi))
347  return true;
348  return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) &&
349  (MIa.getOperand(0).getReg() == MIb.getOperand(0).getReg()));
350 }
351 }
352 
353 namespace {
354 bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI) {
355  assert(HexagonMCInstrInfo::isBundle(MCI));
356  bool JExtended = false;
357  for (MCInst::iterator J =
359  J != MCI.end(); ++J) {
360  MCInst const *JumpInst = J->getInst();
361  if (HexagonMCInstrInfo::isImmext(*JumpInst)) {
362  JExtended = true;
363  continue;
364  }
365  if (llvm::HexagonMCInstrInfo::getType(MCII, *JumpInst) ==
367  // Try to pair with another insn (B)undled with jump.
368  bool BExtended = false;
369  for (MCInst::iterator B =
371  B != MCI.end(); ++B) {
372  MCInst const *Inst = B->getInst();
373  if (JumpInst == Inst)
374  continue;
375  if (HexagonMCInstrInfo::isImmext(*Inst)) {
376  BExtended = true;
377  continue;
378  }
379  DEBUG(dbgs() << "J,B: " << JumpInst->getOpcode() << ","
380  << Inst->getOpcode() << "\n");
381  if (isOrderedCompoundPair(*Inst, BExtended, *JumpInst, JExtended)) {
382  MCInst *CompoundInsn = getCompoundInsn(Context, *Inst, *JumpInst);
383  if (CompoundInsn) {
384  DEBUG(dbgs() << "B: " << Inst->getOpcode() << ","
385  << JumpInst->getOpcode() << " Compounds to "
386  << CompoundInsn->getOpcode() << "\n");
387  J->setInst(CompoundInsn);
388  MCI.erase(B);
389  return true;
390  }
391  }
392  BExtended = false;
393  }
394  }
395  JExtended = false;
396  }
397  return false;
398 }
399 }
400 
401 /// tryCompound - Given a bundle check for compound insns when one
402 /// is found update the contents fo the bundle with the compound insn.
403 /// If a compound instruction is found then the bundle will have one
404 /// additional slot.
406  MCContext &Context, MCInst &MCI) {
407  assert(MCI.getOpcode() == Hexagon::BUNDLE &&
408  "Non-Bundle where Bundle expected");
409 
410  // By definition a compound must have 2 insn.
411  if (MCI.size() < 2)
412  return;
413 
414  // Look for compounds until none are found, only update the bundle when
415  // a compound is found.
416  while (lookForCompound(MCII, Context, MCI))
417  ;
418 
419  return;
420 }
iterator end()
Definition: MCInst.h:177
iterator begin()
Definition: MCInst.h:175
void tryCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI)
tryCompound - Given a bundle check for compound insns when one is found update the contents fo the bu...
bool isIntRegForSubInst(unsigned Reg)
bool isBundle(MCInst const &MCI)
static const unsigned tstBitOpcode[8]
bool isImmext(MCInst const &MCI)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
void erase(iterator I)
Definition: MCInst.h:173
static const unsigned cmpeqBitOpcode[8]
Context object for machine code objects.
Definition: MCContext.h:48
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:63
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
bool isImm() const
Definition: MCInst.h:57
static const unsigned cmpgtuBitOpcode[8]
static const unsigned cmpeqiBitOpcode[8]
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
size_t size() const
Definition: MCInst.h:174
void setOpcode(unsigned Op)
Definition: MCInst.h:158
size_t const bundleInstructionsOffset
static const unsigned cmpgtn1BitOpcode[8]
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:123
BUNDLE - This instruction represents an instruction bundle.
Definition: TargetOpcodes.h:91
unsigned getOpcode() const
Definition: MCInst.h:159
int64_t getImm() const
Definition: MCInst.h:74
static const unsigned cmpeqn1BitOpcode[8]
static const unsigned cmpgtiBitOpcode[8]
static const unsigned cmpgtuiBitOpcode[8]
static const unsigned cmpgtBitOpcode[8]
#define DEBUG(X)
Definition: Debug.h:92
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:164