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