Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- HexagonAsmPrinter.cpp - Print machine instrs to Hexagon assembly ---===//
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
// This file contains a printer that converts from our internal representation
10
// of machine-dependent LLVM code to Hexagon assembly language. This printer is
11
// the output mechanism used by `llc'.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "HexagonAsmPrinter.h"
16
#include "Hexagon.h"
17
#include "HexagonInstrInfo.h"
18
#include "HexagonRegisterInfo.h"
19
#include "HexagonSubtarget.h"
20
#include "MCTargetDesc/HexagonInstPrinter.h"
21
#include "MCTargetDesc/HexagonMCExpr.h"
22
#include "MCTargetDesc/HexagonMCInstrInfo.h"
23
#include "MCTargetDesc/HexagonMCTargetDesc.h"
24
#include "TargetInfo/HexagonTargetInfo.h"
25
#include "llvm/ADT/StringExtras.h"
26
#include "llvm/ADT/StringRef.h"
27
#include "llvm/ADT/Twine.h"
28
#include "llvm/BinaryFormat/ELF.h"
29
#include "llvm/CodeGen/AsmPrinter.h"
30
#include "llvm/CodeGen/MachineBasicBlock.h"
31
#include "llvm/CodeGen/MachineFunction.h"
32
#include "llvm/CodeGen/MachineInstr.h"
33
#include "llvm/CodeGen/MachineOperand.h"
34
#include "llvm/CodeGen/TargetRegisterInfo.h"
35
#include "llvm/CodeGen/TargetSubtargetInfo.h"
36
#include "llvm/MC/MCContext.h"
37
#include "llvm/MC/MCDirectives.h"
38
#include "llvm/MC/MCExpr.h"
39
#include "llvm/MC/MCInst.h"
40
#include "llvm/MC/MCRegisterInfo.h"
41
#include "llvm/MC/MCSectionELF.h"
42
#include "llvm/MC/MCStreamer.h"
43
#include "llvm/MC/MCSymbol.h"
44
#include "llvm/Support/Casting.h"
45
#include "llvm/Support/CommandLine.h"
46
#include "llvm/Support/ErrorHandling.h"
47
#include "llvm/Support/TargetRegistry.h"
48
#include "llvm/Support/raw_ostream.h"
49
#include <algorithm>
50
#include <cassert>
51
#include <cstdint>
52
#include <string>
53
54
using namespace llvm;
55
56
namespace llvm {
57
58
void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI,
59
                      MCInst &MCB, HexagonAsmPrinter &AP);
60
61
} // end namespace llvm
62
63
#define DEBUG_TYPE "asm-printer"
64
65
// Given a scalar register return its pair.
66
inline static unsigned getHexagonRegisterPair(unsigned Reg,
67
18
      const MCRegisterInfo *RI) {
68
18
  assert(Hexagon::IntRegsRegClass.contains(Reg));
69
18
  MCSuperRegIterator SR(Reg, RI, false);
70
18
  unsigned Pair = *SR;
71
18
  assert(Hexagon::DoubleRegsRegClass.contains(Pair));
72
18
  return Pair;
73
18
}
74
75
void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
76
83
                                     raw_ostream &O) {
77
83
  const MachineOperand &MO = MI->getOperand(OpNo);
78
83
79
83
  switch (MO.getType()) {
80
83
  default:
81
0
    llvm_unreachable ("<unknown operand type>");
82
83
  case MachineOperand::MO_Register:
83
76
    O << HexagonInstPrinter::getRegisterName(MO.getReg());
84
76
    return;
85
83
  case MachineOperand::MO_Immediate:
86
7
    O << MO.getImm();
87
7
    return;
88
83
  case MachineOperand::MO_MachineBasicBlock:
89
0
    MO.getMBB()->getSymbol()->print(O, MAI);
90
0
    return;
91
83
  case MachineOperand::MO_ConstantPoolIndex:
92
0
    GetCPISymbol(MO.getIndex())->print(O, MAI);
93
0
    return;
94
83
  case MachineOperand::MO_GlobalAddress:
95
0
    PrintSymbolOperand(MO, O);
96
0
    return;
97
83
  }
98
83
}
99
100
// isBlockOnlyReachableByFallthrough - We need to override this since the
101
// default AsmPrinter does not print labels for any basic block that
102
// is only reachable by a fall through. That works for all cases except
103
// for the case in which the basic block is reachable by a fall through but
104
// through an indirect from a jump table. In this case, the jump table
105
// will contain a label not defined by AsmPrinter.
106
bool HexagonAsmPrinter::isBlockOnlyReachableByFallthrough(
107
5.02k
      const MachineBasicBlock *MBB) const {
108
5.02k
  if (MBB->hasAddressTaken())
109
345
    return false;
110
4.68k
  return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB);
111
4.68k
}
112
113
/// PrintAsmOperand - Print out an operand for an inline asm expression.
114
bool HexagonAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
115
                                        const char *ExtraCode,
116
88
                                        raw_ostream &OS) {
117
88
  // Does this asm operand have a single letter operand modifier?
118
88
  if (ExtraCode && 
ExtraCode[0]5
) {
119
5
    if (ExtraCode[1] != 0)
120
0
      return true; // Unknown modifier.
121
5
122
5
    switch (ExtraCode[0]) {
123
5
    default:
124
3
      // See if this is a generic print operand
125
3
      return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS);
126
5
    case 'L':
127
2
    case 'H': { // The highest-numbered register of a pair.
128
2
      const MachineOperand &MO = MI->getOperand(OpNo);
129
2
      const MachineFunction &MF = *MI->getParent()->getParent();
130
2
      const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
131
2
      if (!MO.isReg())
132
0
        return true;
133
2
      unsigned RegNumber = MO.getReg();
134
2
      // This should be an assert in the frontend.
135
2
      if (Hexagon::DoubleRegsRegClass.contains(RegNumber))
136
2
        RegNumber = TRI->getSubReg(RegNumber, ExtraCode[0] == 'L' ?
137
1
                                              Hexagon::isub_lo :
138
2
                                              
Hexagon::isub_hi1
);
139
2
      OS << HexagonInstPrinter::getRegisterName(RegNumber);
140
2
      return false;
141
2
    }
142
2
    case 'I':
143
0
      // Write 'i' if an integer constant, otherwise nothing.  Used to print
144
0
      // addi vs add, etc.
145
0
      if (MI->getOperand(OpNo).isImm())
146
0
        OS << "i";
147
0
      return false;
148
83
    }
149
83
  }
150
83
151
83
  printOperand(MI, OpNo, OS);
152
83
  return false;
153
83
}
154
155
bool HexagonAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
156
                                              unsigned OpNo,
157
                                              const char *ExtraCode,
158
0
                                              raw_ostream &O) {
159
0
  if (ExtraCode && ExtraCode[0])
160
0
    return true; // Unknown modifier.
161
0
162
0
  const MachineOperand &Base  = MI->getOperand(OpNo);
163
0
  const MachineOperand &Offset = MI->getOperand(OpNo+1);
164
0
165
0
  if (Base.isReg())
166
0
    printOperand(MI, OpNo, O);
167
0
  else
168
0
    llvm_unreachable("Unimplemented");
169
0
170
0
  if (Offset.isImm()) {
171
0
    if (Offset.getImm())
172
0
      O << "+#" << Offset.getImm();
173
0
  } else {
174
0
    llvm_unreachable("Unimplemented");
175
0
  }
176
0
177
0
  return false;
178
0
}
179
180
static MCSymbol *smallData(AsmPrinter &AP, const MachineInstr &MI,
181
                           MCStreamer &OutStreamer, const MCOperand &Imm,
182
0
                           int AlignSize) {
183
0
  MCSymbol *Sym;
184
0
  int64_t Value;
185
0
  if (Imm.getExpr()->evaluateAsAbsolute(Value)) {
186
0
    StringRef sectionPrefix;
187
0
    std::string ImmString;
188
0
    StringRef Name;
189
0
    if (AlignSize == 8) {
190
0
       Name = ".CONST_0000000000000000";
191
0
       sectionPrefix = ".gnu.linkonce.l8";
192
0
       ImmString = utohexstr(Value);
193
0
    } else {
194
0
       Name = ".CONST_00000000";
195
0
       sectionPrefix = ".gnu.linkonce.l4";
196
0
       ImmString = utohexstr(static_cast<uint32_t>(Value));
197
0
    }
198
0
199
0
    std::string symbolName =   // Yes, leading zeros are kept.
200
0
      Name.drop_back(ImmString.size()).str() + ImmString;
201
0
    std::string sectionName = sectionPrefix.str() + symbolName;
202
0
203
0
    MCSectionELF *Section = OutStreamer.getContext().getELFSection(
204
0
        sectionName, ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
205
0
    OutStreamer.SwitchSection(Section);
206
0
207
0
    Sym = AP.OutContext.getOrCreateSymbol(Twine(symbolName));
208
0
    if (Sym->isUndefined()) {
209
0
      OutStreamer.EmitLabel(Sym);
210
0
      OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global);
211
0
      OutStreamer.EmitIntValue(Value, AlignSize);
212
0
      OutStreamer.EmitCodeAlignment(AlignSize);
213
0
    }
214
0
  } else {
215
0
    assert(Imm.isExpr() && "Expected expression and found none");
216
0
    const MachineOperand &MO = MI.getOperand(1);
217
0
    assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
218
0
    MCSymbol *MOSymbol = nullptr;
219
0
    if (MO.isGlobal())
220
0
      MOSymbol = AP.getSymbol(MO.getGlobal());
221
0
    else if (MO.isCPI())
222
0
      MOSymbol = AP.GetCPISymbol(MO.getIndex());
223
0
    else if (MO.isJTI())
224
0
      MOSymbol = AP.GetJTISymbol(MO.getIndex());
225
0
    else
226
0
      llvm_unreachable("Unknown operand type!");
227
0
228
0
    StringRef SymbolName = MOSymbol->getName();
229
0
    std::string LitaName = ".CONST_" + SymbolName.str();
230
0
231
0
    MCSectionELF *Section = OutStreamer.getContext().getELFSection(
232
0
        ".lita", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
233
0
234
0
    OutStreamer.SwitchSection(Section);
235
0
    Sym = AP.OutContext.getOrCreateSymbol(Twine(LitaName));
236
0
    if (Sym->isUndefined()) {
237
0
      OutStreamer.EmitLabel(Sym);
238
0
      OutStreamer.EmitSymbolAttribute(Sym, MCSA_Local);
239
0
      OutStreamer.EmitValue(Imm.getExpr(), AlignSize);
240
0
      OutStreamer.EmitCodeAlignment(AlignSize);
241
0
    }
242
0
  }
243
0
  return Sym;
244
0
}
245
246
static MCInst ScaleVectorOffset(MCInst &Inst, unsigned OpNo,
247
2.48k
                                unsigned VectorSize, MCContext &Ctx) {
248
2.48k
  MCInst T;
249
2.48k
  T.setOpcode(Inst.getOpcode());
250
10.1k
  for (unsigned i = 0, n = Inst.getNumOperands(); i != n; 
++i7.62k
) {
251
7.62k
    if (i != OpNo) {
252
5.14k
      T.addOperand(Inst.getOperand(i));
253
5.14k
      continue;
254
5.14k
    }
255
2.48k
    MCOperand &ImmOp = Inst.getOperand(i);
256
2.48k
    const auto *HE = static_cast<const HexagonMCExpr*>(ImmOp.getExpr());
257
2.48k
    int32_t V = cast<MCConstantExpr>(HE->getExpr())->getValue();
258
2.48k
    auto *NewCE = MCConstantExpr::create(V / int32_t(VectorSize), Ctx);
259
2.48k
    auto *NewHE = HexagonMCExpr::create(NewCE, Ctx);
260
2.48k
    T.addOperand(MCOperand::createExpr(NewHE));
261
2.48k
  }
262
2.48k
  return T;
263
2.48k
}
264
265
void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
266
33.4k
                                                  const MachineInstr &MI) {
267
33.4k
  MCInst &MappedInst = static_cast <MCInst &>(Inst);
268
33.4k
  const MCRegisterInfo *RI = OutStreamer->getContext().getRegisterInfo();
269
33.4k
  const MachineFunction &MF = *MI.getParent()->getParent();
270
33.4k
  auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
271
33.4k
  unsigned VectorSize = HRI.getRegSizeInBits(Hexagon::HvxVRRegClass) / 8;
272
33.4k
273
33.4k
  switch (Inst.getOpcode()) {
274
33.4k
  default:
275
30.1k
    return;
276
33.4k
277
33.4k
  case Hexagon::A2_iconst: {
278
0
    Inst.setOpcode(Hexagon::A2_addi);
279
0
    MCOperand Reg = Inst.getOperand(0);
280
0
    MCOperand S16 = Inst.getOperand(1);
281
0
    HexagonMCInstrInfo::setMustNotExtend(*S16.getExpr());
282
0
    HexagonMCInstrInfo::setS27_2_reloc(*S16.getExpr());
283
0
    Inst.clear();
284
0
    Inst.addOperand(Reg);
285
0
    Inst.addOperand(MCOperand::createReg(Hexagon::R0));
286
0
    Inst.addOperand(S16);
287
0
    break;
288
33.4k
  }
289
33.4k
290
33.4k
  case Hexagon::A2_tfrf: {
291
65
    const MCConstantExpr *Zero = MCConstantExpr::create(0, OutContext);
292
65
    Inst.setOpcode(Hexagon::A2_paddif);
293
65
    Inst.addOperand(MCOperand::createExpr(Zero));
294
65
    break;
295
33.4k
  }
296
33.4k
297
33.4k
  case Hexagon::A2_tfrt: {
298
9
    const MCConstantExpr *Zero = MCConstantExpr::create(0, OutContext);
299
9
    Inst.setOpcode(Hexagon::A2_paddit);
300
9
    Inst.addOperand(MCOperand::createExpr(Zero));
301
9
    break;
302
33.4k
  }
303
33.4k
304
33.4k
  case Hexagon::A2_tfrfnew: {
305
9
    const MCConstantExpr *Zero = MCConstantExpr::create(0, OutContext);
306
9
    Inst.setOpcode(Hexagon::A2_paddifnew);
307
9
    Inst.addOperand(MCOperand::createExpr(Zero));
308
9
    break;
309
33.4k
  }
310
33.4k
311
33.4k
  case Hexagon::A2_tfrtnew: {
312
5
    const MCConstantExpr *Zero = MCConstantExpr::create(0, OutContext);
313
5
    Inst.setOpcode(Hexagon::A2_padditnew);
314
5
    Inst.addOperand(MCOperand::createExpr(Zero));
315
5
    break;
316
33.4k
  }
317
33.4k
318
33.4k
  case Hexagon::A2_zxtb: {
319
55
    const MCConstantExpr *C255 = MCConstantExpr::create(255, OutContext);
320
55
    Inst.setOpcode(Hexagon::A2_andir);
321
55
    Inst.addOperand(MCOperand::createExpr(C255));
322
55
    break;
323
33.4k
  }
324
33.4k
325
33.4k
  // "$dst = CONST64(#$src1)",
326
33.4k
  case Hexagon::CONST64:
327
52
    if (!OutStreamer->hasRawTextSupport()) {
328
0
      const MCOperand &Imm = MappedInst.getOperand(1);
329
0
      MCSectionSubPair Current = OutStreamer->getCurrentSection();
330
0
331
0
      MCSymbol *Sym = smallData(*this, MI, *OutStreamer, Imm, 8);
332
0
333
0
      OutStreamer->SwitchSection(Current.first, Current.second);
334
0
      MCInst TmpInst;
335
0
      MCOperand &Reg = MappedInst.getOperand(0);
336
0
      TmpInst.setOpcode(Hexagon::L2_loadrdgp);
337
0
      TmpInst.addOperand(Reg);
338
0
      TmpInst.addOperand(MCOperand::createExpr(
339
0
                         MCSymbolRefExpr::create(Sym, OutContext)));
340
0
      MappedInst = TmpInst;
341
0
342
0
    }
343
52
    break;
344
33.4k
  case Hexagon::CONST32:
345
0
    if (!OutStreamer->hasRawTextSupport()) {
346
0
      MCOperand &Imm = MappedInst.getOperand(1);
347
0
      MCSectionSubPair Current = OutStreamer->getCurrentSection();
348
0
      MCSymbol *Sym = smallData(*this, MI, *OutStreamer, Imm, 4);
349
0
      OutStreamer->SwitchSection(Current.first, Current.second);
350
0
      MCInst TmpInst;
351
0
      MCOperand &Reg = MappedInst.getOperand(0);
352
0
      TmpInst.setOpcode(Hexagon::L2_loadrigp);
353
0
      TmpInst.addOperand(Reg);
354
0
      TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
355
0
          MCSymbolRefExpr::create(Sym, OutContext), OutContext)));
356
0
      MappedInst = TmpInst;
357
0
    }
358
0
    break;
359
33.4k
360
33.4k
  // C2_pxfer_map maps to C2_or instruction. Though, it's possible to use
361
33.4k
  // C2_or during instruction selection itself but it results
362
33.4k
  // into suboptimal code.
363
33.4k
  case Hexagon::C2_pxfer_map: {
364
0
    MCOperand &Ps = Inst.getOperand(1);
365
0
    MappedInst.setOpcode(Hexagon::C2_or);
366
0
    MappedInst.addOperand(Ps);
367
0
    return;
368
33.4k
  }
369
33.4k
370
33.4k
  // Vector reduce complex multiply by scalar, Rt & 1 map to :hi else :lo
371
33.4k
  // The insn is mapped from the 4 operand to the 3 operand raw form taking
372
33.4k
  // 3 register pairs.
373
33.4k
  case Hexagon::M2_vrcmpys_acc_s1: {
374
2
    MCOperand &Rt = Inst.getOperand(3);
375
2
    assert(Rt.isReg() && "Expected register and none was found");
376
2
    unsigned Reg = RI->getEncodingValue(Rt.getReg());
377
2
    if (Reg & 1)
378
1
      MappedInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
379
1
    else
380
1
      MappedInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
381
2
    Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI));
382
2
    return;
383
33.4k
  }
384
33.4k
  case Hexagon::M2_vrcmpys_s1: {
385
2
    MCOperand &Rt = Inst.getOperand(2);
386
2
    assert(Rt.isReg() && "Expected register and none was found");
387
2
    unsigned Reg = RI->getEncodingValue(Rt.getReg());
388
2
    if (Reg & 1)
389
1
      MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
390
1
    else
391
1
      MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
392
2
    Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI));
393
2
    return;
394
33.4k
  }
395
33.4k
396
33.4k
  case Hexagon::M2_vrcmpys_s1rp: {
397
0
    MCOperand &Rt = Inst.getOperand(2);
398
0
    assert(Rt.isReg() && "Expected register and none was found");
399
0
    unsigned Reg = RI->getEncodingValue(Rt.getReg());
400
0
    if (Reg & 1)
401
0
      MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
402
0
    else
403
0
      MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
404
0
    Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI));
405
0
    return;
406
33.4k
  }
407
33.4k
408
33.4k
  case Hexagon::A4_boundscheck: {
409
0
    MCOperand &Rs = Inst.getOperand(1);
410
0
    assert(Rs.isReg() && "Expected register and none was found");
411
0
    unsigned Reg = RI->getEncodingValue(Rs.getReg());
412
0
    if (Reg & 1) // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
413
0
      MappedInst.setOpcode(Hexagon::A4_boundscheck_hi);
414
0
    else         // raw:lo
415
0
      MappedInst.setOpcode(Hexagon::A4_boundscheck_lo);
416
0
    Rs.setReg(getHexagonRegisterPair(Rs.getReg(), RI));
417
0
    return;
418
33.4k
  }
419
33.4k
420
33.4k
  case Hexagon::PS_call_nr:
421
45
    Inst.setOpcode(Hexagon::J2_call);
422
45
    break;
423
33.4k
424
33.4k
  case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
425
0
    MCOperand &MO = MappedInst.getOperand(2);
426
0
    int64_t Imm;
427
0
    MCExpr const *Expr = MO.getExpr();
428
0
    bool Success = Expr->evaluateAsAbsolute(Imm);
429
0
    assert(Success && "Expected immediate and none was found");
430
0
    (void)Success;
431
0
    MCInst TmpInst;
432
0
    if (Imm == 0) {
433
0
      TmpInst.setOpcode(Hexagon::S2_vsathub);
434
0
      TmpInst.addOperand(MappedInst.getOperand(0));
435
0
      TmpInst.addOperand(MappedInst.getOperand(1));
436
0
      MappedInst = TmpInst;
437
0
      return;
438
0
    }
439
0
    TmpInst.setOpcode(Hexagon::S5_asrhub_rnd_sat);
440
0
    TmpInst.addOperand(MappedInst.getOperand(0));
441
0
    TmpInst.addOperand(MappedInst.getOperand(1));
442
0
    const MCExpr *One = MCConstantExpr::create(1, OutContext);
443
0
    const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext);
444
0
    TmpInst.addOperand(
445
0
        MCOperand::createExpr(HexagonMCExpr::create(Sub, OutContext)));
446
0
    MappedInst = TmpInst;
447
0
    return;
448
0
  }
449
0
450
0
  case Hexagon::S5_vasrhrnd_goodsyntax:
451
0
  case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
452
0
    MCOperand &MO2 = MappedInst.getOperand(2);
453
0
    MCExpr const *Expr = MO2.getExpr();
454
0
    int64_t Imm;
455
0
    bool Success = Expr->evaluateAsAbsolute(Imm);
456
0
    assert(Success && "Expected immediate and none was found");
457
0
    (void)Success;
458
0
    MCInst TmpInst;
459
0
    if (Imm == 0) {
460
0
      TmpInst.setOpcode(Hexagon::A2_combinew);
461
0
      TmpInst.addOperand(MappedInst.getOperand(0));
462
0
      MCOperand &MO1 = MappedInst.getOperand(1);
463
0
      unsigned High = RI->getSubReg(MO1.getReg(), Hexagon::isub_hi);
464
0
      unsigned Low = RI->getSubReg(MO1.getReg(), Hexagon::isub_lo);
465
0
      // Add a new operand for the second register in the pair.
466
0
      TmpInst.addOperand(MCOperand::createReg(High));
467
0
      TmpInst.addOperand(MCOperand::createReg(Low));
468
0
      MappedInst = TmpInst;
469
0
      return;
470
0
    }
471
0
472
0
    if (Inst.getOpcode() == Hexagon::S2_asr_i_p_rnd_goodsyntax)
473
0
      TmpInst.setOpcode(Hexagon::S2_asr_i_p_rnd);
474
0
    else
475
0
      TmpInst.setOpcode(Hexagon::S5_vasrhrnd);
476
0
    TmpInst.addOperand(MappedInst.getOperand(0));
477
0
    TmpInst.addOperand(MappedInst.getOperand(1));
478
0
    const MCExpr *One = MCConstantExpr::create(1, OutContext);
479
0
    const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext);
480
0
    TmpInst.addOperand(
481
0
        MCOperand::createExpr(HexagonMCExpr::create(Sub, OutContext)));
482
0
    MappedInst = TmpInst;
483
0
    return;
484
0
  }
485
0
486
0
  // if ("#u5==0") Assembler mapped to: "Rd=Rs"; else Rd=asr(Rs,#u5-1):rnd
487
0
  case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
488
0
    MCOperand &MO = Inst.getOperand(2);
489
0
    MCExpr const *Expr = MO.getExpr();
490
0
    int64_t Imm;
491
0
    bool Success = Expr->evaluateAsAbsolute(Imm);
492
0
    assert(Success && "Expected immediate and none was found");
493
0
    (void)Success;
494
0
    MCInst TmpInst;
495
0
    if (Imm == 0) {
496
0
      TmpInst.setOpcode(Hexagon::A2_tfr);
497
0
      TmpInst.addOperand(MappedInst.getOperand(0));
498
0
      TmpInst.addOperand(MappedInst.getOperand(1));
499
0
      MappedInst = TmpInst;
500
0
      return;
501
0
    }
502
0
    TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);
503
0
    TmpInst.addOperand(MappedInst.getOperand(0));
504
0
    TmpInst.addOperand(MappedInst.getOperand(1));
505
0
    const MCExpr *One = MCConstantExpr::create(1, OutContext);
506
0
    const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext);
507
0
    TmpInst.addOperand(
508
0
        MCOperand::createExpr(HexagonMCExpr::create(Sub, OutContext)));
509
0
    MappedInst = TmpInst;
510
0
    return;
511
0
  }
512
0
513
0
  // Translate a "$Rdd = #imm" to "$Rdd = combine(#[-1,0], #imm)"
514
64
  case Hexagon::A2_tfrpi: {
515
64
    MCInst TmpInst;
516
64
    MCOperand &Rdd = MappedInst.getOperand(0);
517
64
    MCOperand &MO = MappedInst.getOperand(1);
518
64
519
64
    TmpInst.setOpcode(Hexagon::A2_combineii);
520
64
    TmpInst.addOperand(Rdd);
521
64
    int64_t Imm;
522
64
    bool Success = MO.getExpr()->evaluateAsAbsolute(Imm);
523
64
    if (Success && Imm < 0) {
524
5
      const MCExpr *MOne = MCConstantExpr::create(-1, OutContext);
525
5
      const HexagonMCExpr *E = HexagonMCExpr::create(MOne, OutContext);
526
5
      TmpInst.addOperand(MCOperand::createExpr(E));
527
59
    } else {
528
59
      const MCExpr *Zero = MCConstantExpr::create(0, OutContext);
529
59
      const HexagonMCExpr *E = HexagonMCExpr::create(Zero, OutContext);
530
59
      TmpInst.addOperand(MCOperand::createExpr(E));
531
59
    }
532
64
    TmpInst.addOperand(MO);
533
64
    MappedInst = TmpInst;
534
64
    return;
535
0
  }
536
0
537
0
  // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
538
423
  case Hexagon::A2_tfrp: {
539
423
    MCOperand &MO = MappedInst.getOperand(1);
540
423
    unsigned High = RI->getSubReg(MO.getReg(), Hexagon::isub_hi);
541
423
    unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::isub_lo);
542
423
    MO.setReg(High);
543
423
    // Add a new operand for the second register in the pair.
544
423
    MappedInst.addOperand(MCOperand::createReg(Low));
545
423
    MappedInst.setOpcode(Hexagon::A2_combinew);
546
423
    return;
547
0
  }
548
0
549
5
  case Hexagon::A2_tfrpt:
550
5
  case Hexagon::A2_tfrpf: {
551
5
    MCOperand &MO = MappedInst.getOperand(2);
552
5
    unsigned High = RI->getSubReg(MO.getReg(), Hexagon::isub_hi);
553
5
    unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::isub_lo);
554
5
    MO.setReg(High);
555
5
    // Add a new operand for the second register in the pair.
556
5
    MappedInst.addOperand(MCOperand::createReg(Low));
557
5
    MappedInst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
558
5
                          ? 
Hexagon::C2_ccombinewt3
559
5
                          : 
Hexagon::C2_ccombinewf2
);
560
5
    return;
561
5
  }
562
5
563
5
  case Hexagon::A2_tfrptnew:
564
0
  case Hexagon::A2_tfrpfnew: {
565
0
    MCOperand &MO = MappedInst.getOperand(2);
566
0
    unsigned High = RI->getSubReg(MO.getReg(), Hexagon::isub_hi);
567
0
    unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::isub_lo);
568
0
    MO.setReg(High);
569
0
    // Add a new operand for the second register in the pair.
570
0
    MappedInst.addOperand(MCOperand::createReg(Low));
571
0
    MappedInst.setOpcode(Inst.getOpcode() == Hexagon::A2_tfrptnew
572
0
                            ? Hexagon::C2_ccombinewnewt
573
0
                            : Hexagon::C2_ccombinewnewf);
574
0
    return;
575
0
  }
576
0
577
1
  case Hexagon::M2_mpysmi: {
578
1
    MCOperand &Imm = MappedInst.getOperand(2);
579
1
    MCExpr const *Expr = Imm.getExpr();
580
1
    int64_t Value;
581
1
    bool Success = Expr->evaluateAsAbsolute(Value);
582
1
    assert(Success);
583
1
    (void)Success;
584
1
    if (Value < 0 && Value > -256) {
585
0
      MappedInst.setOpcode(Hexagon::M2_mpysin);
586
0
      Imm.setExpr(HexagonMCExpr::create(
587
0
          MCUnaryExpr::createMinus(Expr, OutContext), OutContext));
588
0
    } else
589
1
      MappedInst.setOpcode(Hexagon::M2_mpysip);
590
1
    return;
591
0
  }
592
0
593
14
  case Hexagon::A2_addsp: {
594
14
    MCOperand &Rt = Inst.getOperand(1);
595
14
    assert(Rt.isReg() && "Expected register and none was found");
596
14
    unsigned Reg = RI->getEncodingValue(Rt.getReg());
597
14
    if (Reg & 1)
598
9
      MappedInst.setOpcode(Hexagon::A2_addsph);
599
5
    else
600
5
      MappedInst.setOpcode(Hexagon::A2_addspl);
601
14
    Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI));
602
14
    return;
603
0
  }
604
0
605
59
  case Hexagon::V6_vd0: {
606
59
    MCInst TmpInst;
607
59
    assert(Inst.getOperand(0).isReg() &&
608
59
           "Expected register and none was found");
609
59
610
59
    TmpInst.setOpcode(Hexagon::V6_vxor);
611
59
    TmpInst.addOperand(Inst.getOperand(0));
612
59
    TmpInst.addOperand(Inst.getOperand(0));
613
59
    TmpInst.addOperand(Inst.getOperand(0));
614
59
    MappedInst = TmpInst;
615
59
    return;
616
0
  }
617
0
618
2
  case Hexagon::V6_vdd0: {
619
2
    MCInst TmpInst;
620
2
    assert (Inst.getOperand(0).isReg() &&
621
2
            "Expected register and none was found");
622
2
623
2
    TmpInst.setOpcode(Hexagon::V6_vsubw_dv);
624
2
    TmpInst.addOperand(Inst.getOperand(0));
625
2
    TmpInst.addOperand(Inst.getOperand(0));
626
2
    TmpInst.addOperand(Inst.getOperand(0));
627
2
    MappedInst = TmpInst;
628
2
    return;
629
0
  }
630
0
631
100
  case Hexagon::V6_vL32Ub_pi:
632
100
  case Hexagon::V6_vL32b_cur_pi:
633
100
  case Hexagon::V6_vL32b_nt_cur_pi:
634
100
  case Hexagon::V6_vL32b_pi:
635
100
  case Hexagon::V6_vL32b_nt_pi:
636
100
  case Hexagon::V6_vL32b_nt_tmp_pi:
637
100
  case Hexagon::V6_vL32b_tmp_pi:
638
100
    MappedInst = ScaleVectorOffset(Inst, 3, VectorSize, OutContext);
639
100
    return;
640
100
641
1.34k
  case Hexagon::V6_vL32Ub_ai:
642
1.34k
  case Hexagon::V6_vL32b_ai:
643
1.34k
  case Hexagon::V6_vL32b_cur_ai:
644
1.34k
  case Hexagon::V6_vL32b_nt_ai:
645
1.34k
  case Hexagon::V6_vL32b_nt_cur_ai:
646
1.34k
  case Hexagon::V6_vL32b_nt_tmp_ai:
647
1.34k
  case Hexagon::V6_vL32b_tmp_ai:
648
1.34k
    MappedInst = ScaleVectorOffset(Inst, 2, VectorSize, OutContext);
649
1.34k
    return;
650
1.34k
651
1.34k
  case Hexagon::V6_vS32Ub_pi:
652
41
  case Hexagon::V6_vS32b_new_pi:
653
41
  case Hexagon::V6_vS32b_nt_new_pi:
654
41
  case Hexagon::V6_vS32b_nt_pi:
655
41
  case Hexagon::V6_vS32b_pi:
656
41
    MappedInst = ScaleVectorOffset(Inst, 2, VectorSize, OutContext);
657
41
    return;
658
41
659
983
  case Hexagon::V6_vS32Ub_ai:
660
983
  case Hexagon::V6_vS32b_ai:
661
983
  case Hexagon::V6_vS32b_new_ai:
662
983
  case Hexagon::V6_vS32b_nt_ai:
663
983
  case Hexagon::V6_vS32b_nt_new_ai:
664
983
    MappedInst = ScaleVectorOffset(Inst, 1, VectorSize, OutContext);
665
983
    return;
666
983
667
983
  case Hexagon::V6_vL32b_cur_npred_pi:
668
0
  case Hexagon::V6_vL32b_cur_pred_pi:
669
0
  case Hexagon::V6_vL32b_npred_pi:
670
0
  case Hexagon::V6_vL32b_nt_cur_npred_pi:
671
0
  case Hexagon::V6_vL32b_nt_cur_pred_pi:
672
0
  case Hexagon::V6_vL32b_nt_npred_pi:
673
0
  case Hexagon::V6_vL32b_nt_pred_pi:
674
0
  case Hexagon::V6_vL32b_nt_tmp_npred_pi:
675
0
  case Hexagon::V6_vL32b_nt_tmp_pred_pi:
676
0
  case Hexagon::V6_vL32b_pred_pi:
677
0
  case Hexagon::V6_vL32b_tmp_npred_pi:
678
0
  case Hexagon::V6_vL32b_tmp_pred_pi:
679
0
    MappedInst = ScaleVectorOffset(Inst, 4, VectorSize, OutContext);
680
0
    return;
681
0
682
0
  case Hexagon::V6_vL32b_cur_npred_ai:
683
0
  case Hexagon::V6_vL32b_cur_pred_ai:
684
0
  case Hexagon::V6_vL32b_npred_ai:
685
0
  case Hexagon::V6_vL32b_nt_cur_npred_ai:
686
0
  case Hexagon::V6_vL32b_nt_cur_pred_ai:
687
0
  case Hexagon::V6_vL32b_nt_npred_ai:
688
0
  case Hexagon::V6_vL32b_nt_pred_ai:
689
0
  case Hexagon::V6_vL32b_nt_tmp_npred_ai:
690
0
  case Hexagon::V6_vL32b_nt_tmp_pred_ai:
691
0
  case Hexagon::V6_vL32b_pred_ai:
692
0
  case Hexagon::V6_vL32b_tmp_npred_ai:
693
0
  case Hexagon::V6_vL32b_tmp_pred_ai:
694
0
    MappedInst = ScaleVectorOffset(Inst, 3, VectorSize, OutContext);
695
0
    return;
696
0
697
2
  case Hexagon::V6_vS32Ub_npred_pi:
698
2
  case Hexagon::V6_vS32Ub_pred_pi:
699
2
  case Hexagon::V6_vS32b_new_npred_pi:
700
2
  case Hexagon::V6_vS32b_new_pred_pi:
701
2
  case Hexagon::V6_vS32b_npred_pi:
702
2
  case Hexagon::V6_vS32b_nqpred_pi:
703
2
  case Hexagon::V6_vS32b_nt_new_npred_pi:
704
2
  case Hexagon::V6_vS32b_nt_new_pred_pi:
705
2
  case Hexagon::V6_vS32b_nt_npred_pi:
706
2
  case Hexagon::V6_vS32b_nt_nqpred_pi:
707
2
  case Hexagon::V6_vS32b_nt_pred_pi:
708
2
  case Hexagon::V6_vS32b_nt_qpred_pi:
709
2
  case Hexagon::V6_vS32b_pred_pi:
710
2
  case Hexagon::V6_vS32b_qpred_pi:
711
2
    MappedInst = ScaleVectorOffset(Inst, 3, VectorSize, OutContext);
712
2
    return;
713
2
714
17
  case Hexagon::V6_vS32Ub_npred_ai:
715
17
  case Hexagon::V6_vS32Ub_pred_ai:
716
17
  case Hexagon::V6_vS32b_new_npred_ai:
717
17
  case Hexagon::V6_vS32b_new_pred_ai:
718
17
  case Hexagon::V6_vS32b_npred_ai:
719
17
  case Hexagon::V6_vS32b_nqpred_ai:
720
17
  case Hexagon::V6_vS32b_nt_new_npred_ai:
721
17
  case Hexagon::V6_vS32b_nt_new_pred_ai:
722
17
  case Hexagon::V6_vS32b_nt_npred_ai:
723
17
  case Hexagon::V6_vS32b_nt_nqpred_ai:
724
17
  case Hexagon::V6_vS32b_nt_pred_ai:
725
17
  case Hexagon::V6_vS32b_nt_qpred_ai:
726
17
  case Hexagon::V6_vS32b_pred_ai:
727
17
  case Hexagon::V6_vS32b_qpred_ai:
728
17
    MappedInst = ScaleVectorOffset(Inst, 2, VectorSize, OutContext);
729
17
    return;
730
17
731
17
  // V65+
732
17
  case Hexagon::V6_vS32b_srls_ai:
733
0
    MappedInst = ScaleVectorOffset(Inst, 1, VectorSize, OutContext);
734
0
    return;
735
17
736
17
  case Hexagon::V6_vS32b_srls_pi:
737
0
    MappedInst = ScaleVectorOffset(Inst, 2, VectorSize, OutContext);
738
0
    return;
739
33.4k
  }
740
33.4k
}
741
742
/// Print out a single Hexagon MI to the current output stream.
743
20.9k
void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
744
20.9k
  MCInst MCB;
745
20.9k
  MCB.setOpcode(Hexagon::BUNDLE);
746
20.9k
  MCB.addOperand(MCOperand::createImm(0));
747
20.9k
  const MCInstrInfo &MCII = *Subtarget->getInstrInfo();
748
20.9k
749
20.9k
  if (MI->isBundle()) {
750
8.95k
    const MachineBasicBlock* MBB = MI->getParent();
751
8.95k
    MachineBasicBlock::const_instr_iterator MII = MI->getIterator();
752
8.95k
753
30.7k
    for (++MII; MII != MBB->instr_end() && 
MII->isInsideBundle()26.9k
;
++MII21.7k
)
754
21.7k
      if (!MII->isDebugInstr() && !MII->isImplicitDef())
755
21.7k
        HexagonLowerToMC(MCII, &*MII, MCB, *this);
756
11.9k
  } else {
757
11.9k
    HexagonLowerToMC(MCII, MI, MCB, *this);
758
11.9k
  }
759
20.9k
760
20.9k
  const MachineFunction &MF = *MI->getParent()->getParent();
761
20.9k
  const auto &HII = *MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
762
20.9k
  if (MI->isBundle() && 
HII.getBundleNoShuf(*MI)8.95k
)
763
1
    HexagonMCInstrInfo::setMemReorderDisabled(MCB);
764
20.9k
765
20.9k
  MCContext &Ctx = OutStreamer->getContext();
766
20.9k
  bool Ok = HexagonMCInstrInfo::canonicalizePacket(MCII, *Subtarget, Ctx,
767
20.9k
                                                   MCB, nullptr);
768
20.9k
  assert(Ok); (void)Ok;
769
20.9k
  if (HexagonMCInstrInfo::bundleSize(MCB) == 0)
770
0
    return;
771
20.9k
  OutStreamer->EmitInstruction(MCB, getSubtargetInfo());
772
20.9k
}
773
774
78.9k
extern "C" void LLVMInitializeHexagonAsmPrinter() {
775
78.9k
  RegisterAsmPrinter<HexagonAsmPrinter> X(getTheHexagonTarget());
776
78.9k
}