]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp
Update bmake to version 20180919
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / Hexagon / HexagonAsmPrinter.cpp
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/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 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   case Hexagon::V6_vdd0: {
619     MCInst TmpInst;
620     assert (Inst.getOperand(0).isReg() &&
621             "Expected register and none was found");
622
623     TmpInst.setOpcode(Hexagon::V6_vsubw_dv);
624     TmpInst.addOperand(Inst.getOperand(0));
625     TmpInst.addOperand(Inst.getOperand(0));
626     TmpInst.addOperand(Inst.getOperand(0));
627     MappedInst = TmpInst;
628     return;
629   }
630   case Hexagon::V6_vL32Ub_pi:
631   case Hexagon::V6_vL32b_cur_pi:
632   case Hexagon::V6_vL32b_nt_cur_pi:
633   case Hexagon::V6_vL32b_pi:
634   case Hexagon::V6_vL32b_nt_pi:
635   case Hexagon::V6_vL32b_nt_tmp_pi:
636   case Hexagon::V6_vL32b_tmp_pi:
637     MappedInst = ScaleVectorOffset(Inst, 3, VectorSize, OutContext);
638     return;
639
640   case Hexagon::V6_vL32Ub_ai:
641   case Hexagon::V6_vL32b_ai:
642   case Hexagon::V6_vL32b_cur_ai:
643   case Hexagon::V6_vL32b_nt_ai:
644   case Hexagon::V6_vL32b_nt_cur_ai:
645   case Hexagon::V6_vL32b_nt_tmp_ai:
646   case Hexagon::V6_vL32b_tmp_ai:
647     MappedInst = ScaleVectorOffset(Inst, 2, VectorSize, OutContext);
648     return;
649
650   case Hexagon::V6_vS32Ub_pi:
651   case Hexagon::V6_vS32b_new_pi:
652   case Hexagon::V6_vS32b_nt_new_pi:
653   case Hexagon::V6_vS32b_nt_pi:
654   case Hexagon::V6_vS32b_pi:
655     MappedInst = ScaleVectorOffset(Inst, 2, VectorSize, OutContext);
656     return;
657
658   case Hexagon::V6_vS32Ub_ai:
659   case Hexagon::V6_vS32b_ai:
660   case Hexagon::V6_vS32b_new_ai:
661   case Hexagon::V6_vS32b_nt_ai:
662   case Hexagon::V6_vS32b_nt_new_ai:
663     MappedInst = ScaleVectorOffset(Inst, 1, VectorSize, OutContext);
664     return;
665
666   case Hexagon::V6_vL32b_cur_npred_pi:
667   case Hexagon::V6_vL32b_cur_pred_pi:
668   case Hexagon::V6_vL32b_npred_pi:
669   case Hexagon::V6_vL32b_nt_cur_npred_pi:
670   case Hexagon::V6_vL32b_nt_cur_pred_pi:
671   case Hexagon::V6_vL32b_nt_npred_pi:
672   case Hexagon::V6_vL32b_nt_pred_pi:
673   case Hexagon::V6_vL32b_nt_tmp_npred_pi:
674   case Hexagon::V6_vL32b_nt_tmp_pred_pi:
675   case Hexagon::V6_vL32b_pred_pi:
676   case Hexagon::V6_vL32b_tmp_npred_pi:
677   case Hexagon::V6_vL32b_tmp_pred_pi:
678     MappedInst = ScaleVectorOffset(Inst, 4, VectorSize, OutContext);
679     return;
680
681   case Hexagon::V6_vL32b_cur_npred_ai:
682   case Hexagon::V6_vL32b_cur_pred_ai:
683   case Hexagon::V6_vL32b_npred_ai:
684   case Hexagon::V6_vL32b_nt_cur_npred_ai:
685   case Hexagon::V6_vL32b_nt_cur_pred_ai:
686   case Hexagon::V6_vL32b_nt_npred_ai:
687   case Hexagon::V6_vL32b_nt_pred_ai:
688   case Hexagon::V6_vL32b_nt_tmp_npred_ai:
689   case Hexagon::V6_vL32b_nt_tmp_pred_ai:
690   case Hexagon::V6_vL32b_pred_ai:
691   case Hexagon::V6_vL32b_tmp_npred_ai:
692   case Hexagon::V6_vL32b_tmp_pred_ai:
693     MappedInst = ScaleVectorOffset(Inst, 3, VectorSize, OutContext);
694     return;
695
696   case Hexagon::V6_vS32Ub_npred_pi:
697   case Hexagon::V6_vS32Ub_pred_pi:
698   case Hexagon::V6_vS32b_new_npred_pi:
699   case Hexagon::V6_vS32b_new_pred_pi:
700   case Hexagon::V6_vS32b_npred_pi:
701   case Hexagon::V6_vS32b_nqpred_pi:
702   case Hexagon::V6_vS32b_nt_new_npred_pi:
703   case Hexagon::V6_vS32b_nt_new_pred_pi:
704   case Hexagon::V6_vS32b_nt_npred_pi:
705   case Hexagon::V6_vS32b_nt_nqpred_pi:
706   case Hexagon::V6_vS32b_nt_pred_pi:
707   case Hexagon::V6_vS32b_nt_qpred_pi:
708   case Hexagon::V6_vS32b_pred_pi:
709   case Hexagon::V6_vS32b_qpred_pi:
710     MappedInst = ScaleVectorOffset(Inst, 3, VectorSize, OutContext);
711     return;
712
713   case Hexagon::V6_vS32Ub_npred_ai:
714   case Hexagon::V6_vS32Ub_pred_ai:
715   case Hexagon::V6_vS32b_new_npred_ai:
716   case Hexagon::V6_vS32b_new_pred_ai:
717   case Hexagon::V6_vS32b_npred_ai:
718   case Hexagon::V6_vS32b_nqpred_ai:
719   case Hexagon::V6_vS32b_nt_new_npred_ai:
720   case Hexagon::V6_vS32b_nt_new_pred_ai:
721   case Hexagon::V6_vS32b_nt_npred_ai:
722   case Hexagon::V6_vS32b_nt_nqpred_ai:
723   case Hexagon::V6_vS32b_nt_pred_ai:
724   case Hexagon::V6_vS32b_nt_qpred_ai:
725   case Hexagon::V6_vS32b_pred_ai:
726   case Hexagon::V6_vS32b_qpred_ai:
727     MappedInst = ScaleVectorOffset(Inst, 2, VectorSize, OutContext);
728     return;
729
730   // V65+
731   case Hexagon::V6_vS32b_srls_ai:
732     MappedInst = ScaleVectorOffset(Inst, 1, VectorSize, OutContext);
733     return;
734
735   case Hexagon::V6_vS32b_srls_pi:
736     MappedInst = ScaleVectorOffset(Inst, 2, VectorSize, OutContext);
737     return;
738
739   }
740 }
741
742 /// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to
743 /// the current output stream.
744 void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
745   MCInst MCB;
746   MCB.setOpcode(Hexagon::BUNDLE);
747   MCB.addOperand(MCOperand::createImm(0));
748   const MCInstrInfo &MCII = *Subtarget->getInstrInfo();
749
750   if (MI->isBundle()) {
751     const MachineBasicBlock* MBB = MI->getParent();
752     MachineBasicBlock::const_instr_iterator MII = MI->getIterator();
753
754     for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII)
755       if (!MII->isDebugValue() && !MII->isImplicitDef())
756         HexagonLowerToMC(MCII, &*MII, MCB, *this);
757   }
758   else
759     HexagonLowerToMC(MCII, MI, MCB, *this);
760
761   bool Ok = HexagonMCInstrInfo::canonicalizePacket(
762       MCII, *Subtarget, OutStreamer->getContext(), MCB, nullptr);
763   assert(Ok);
764   (void)Ok;
765   if(HexagonMCInstrInfo::bundleSize(MCB) == 0)
766     return;
767   OutStreamer->EmitInstruction(MCB, getSubtargetInfo());
768 }
769
770 extern "C" void LLVMInitializeHexagonAsmPrinter() {
771   RegisterAsmPrinter<HexagonAsmPrinter> X(getTheHexagonTarget());
772 }