]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp
Merge ^/head r312968 through r313054.
[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 "Hexagon.h"
17 #include "HexagonAsmPrinter.h"
18 #include "HexagonMachineFunctionInfo.h"
19 #include "HexagonSubtarget.h"
20 #include "HexagonTargetMachine.h"
21 #include "MCTargetDesc/HexagonInstPrinter.h"
22 #include "MCTargetDesc/HexagonMCInstrInfo.h"
23 #include "MCTargetDesc/HexagonMCShuffler.h"
24 #include "llvm/ADT/StringExtras.h"
25 #include "llvm/Analysis/ConstantFolding.h"
26 #include "llvm/CodeGen/AsmPrinter.h"
27 #include "llvm/CodeGen/MachineFunctionPass.h"
28 #include "llvm/CodeGen/MachineInstr.h"
29 #include "llvm/CodeGen/MachineInstrBuilder.h"
30 #include "llvm/CodeGen/MachineModuleInfo.h"
31 #include "llvm/IR/Constants.h"
32 #include "llvm/IR/DataLayout.h"
33 #include "llvm/IR/DerivedTypes.h"
34 #include "llvm/IR/Mangler.h"
35 #include "llvm/IR/Module.h"
36 #include "llvm/MC/MCAsmInfo.h"
37 #include "llvm/MC/MCContext.h"
38 #include "llvm/MC/MCExpr.h"
39 #include "llvm/MC/MCInst.h"
40 #include "llvm/MC/MCSection.h"
41 #include "llvm/MC/MCSectionELF.h"
42 #include "llvm/MC/MCStreamer.h"
43 #include "llvm/MC/MCSymbol.h"
44 #include "llvm/Support/CommandLine.h"
45 #include "llvm/Support/Debug.h"
46 #include "llvm/Support/ELF.h"
47 #include "llvm/Support/Format.h"
48 #include "llvm/Support/MathExtras.h"
49 #include "llvm/Support/TargetRegistry.h"
50 #include "llvm/Support/raw_ostream.h"
51 #include "llvm/Target/TargetInstrInfo.h"
52 #include "llvm/Target/TargetLoweringObjectFile.h"
53 #include "llvm/Target/TargetOptions.h"
54 #include "llvm/Target/TargetRegisterInfo.h"
55
56 using namespace llvm;
57
58 namespace llvm {
59   void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI,
60                         MCInst &MCB, HexagonAsmPrinter &AP);
61 }
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)), Subtarget(nullptr) {}
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 //
110 // isBlockOnlyReachableByFallthrough - We need to override this since the
111 // default AsmPrinter does not print labels for any basic block that
112 // is only reachable by a fall through. That works for all cases except
113 // for the case in which the basic block is reachable by a fall through but
114 // through an indirect from a jump table. In this case, the jump table
115 // will contain a label not defined by AsmPrinter.
116 //
117 bool HexagonAsmPrinter::
118 isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
119   if (MBB->hasAddressTaken())
120     return false;
121   return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB);
122 }
123
124
125 /// PrintAsmOperand - Print out an operand for an inline asm expression.
126 ///
127 bool HexagonAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
128                                         unsigned AsmVariant,
129                                         const char *ExtraCode,
130                                         raw_ostream &OS) {
131   // Does this asm operand have a single letter operand modifier?
132   if (ExtraCode && ExtraCode[0]) {
133     if (ExtraCode[1] != 0)
134       return true; // Unknown modifier.
135
136     switch (ExtraCode[0]) {
137     default:
138       // See if this is a generic print operand
139       return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, OS);
140     case 'c': // Don't print "$" before a global var name or constant.
141       // Hexagon never has a prefix.
142       printOperand(MI, OpNo, OS);
143       return false;
144     case 'L':
145     case 'H': { // The highest-numbered register of a pair.
146       const MachineOperand &MO = MI->getOperand(OpNo);
147       const MachineFunction &MF = *MI->getParent()->getParent();
148       const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
149       if (!MO.isReg())
150         return true;
151       unsigned RegNumber = MO.getReg();
152       // This should be an assert in the frontend.
153       if (Hexagon::DoubleRegsRegClass.contains(RegNumber))
154         RegNumber = TRI->getSubReg(RegNumber, ExtraCode[0] == 'L' ?
155                                               Hexagon::isub_lo :
156                                               Hexagon::isub_hi);
157       OS << HexagonInstPrinter::getRegisterName(RegNumber);
158       return false;
159     }
160     case 'I':
161       // Write 'i' if an integer constant, otherwise nothing.  Used to print
162       // addi vs add, etc.
163       if (MI->getOperand(OpNo).isImm())
164         OS << "i";
165       return false;
166     }
167   }
168
169   printOperand(MI, OpNo, OS);
170   return false;
171 }
172
173 bool HexagonAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
174                                               unsigned OpNo, unsigned AsmVariant,
175                                               const char *ExtraCode,
176                                               raw_ostream &O) {
177   if (ExtraCode && ExtraCode[0])
178     return true; // Unknown modifier.
179
180   const MachineOperand &Base  = MI->getOperand(OpNo);
181   const MachineOperand &Offset = MI->getOperand(OpNo+1);
182
183   if (Base.isReg())
184     printOperand(MI, OpNo, O);
185   else
186     llvm_unreachable("Unimplemented");
187
188   if (Offset.isImm()) {
189     if (Offset.getImm())
190       O << " + #" << Offset.getImm();
191   }
192   else
193     llvm_unreachable("Unimplemented");
194
195   return false;
196 }
197
198 static MCSymbol *smallData(AsmPrinter &AP, const MachineInstr &MI,
199                            MCStreamer &OutStreamer, const MCOperand &Imm,
200                            int AlignSize) {
201   MCSymbol *Sym;
202   int64_t Value;
203   if (Imm.getExpr()->evaluateAsAbsolute(Value)) {
204     StringRef sectionPrefix;
205     std::string ImmString;
206     StringRef Name;
207     if (AlignSize == 8) {
208        Name = ".CONST_0000000000000000";
209        sectionPrefix = ".gnu.linkonce.l8";
210        ImmString = utohexstr(Value);
211     } else {
212        Name = ".CONST_00000000";
213        sectionPrefix = ".gnu.linkonce.l4";
214        ImmString = utohexstr(static_cast<uint32_t>(Value));
215     }
216
217     std::string symbolName =   // Yes, leading zeros are kept.
218       Name.drop_back(ImmString.size()).str() + ImmString;
219     std::string sectionName = sectionPrefix.str() + symbolName;
220
221     MCSectionELF *Section = OutStreamer.getContext().getELFSection(
222         sectionName, ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
223     OutStreamer.SwitchSection(Section);
224
225     Sym = AP.OutContext.getOrCreateSymbol(Twine(symbolName));
226     if (Sym->isUndefined()) {
227       OutStreamer.EmitLabel(Sym);
228       OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global);
229       OutStreamer.EmitIntValue(Value, AlignSize);
230       OutStreamer.EmitCodeAlignment(AlignSize);
231     }
232   } else {
233     assert(Imm.isExpr() && "Expected expression and found none");
234     const MachineOperand &MO = MI.getOperand(1);
235     assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
236     MCSymbol *MOSymbol = nullptr;
237     if (MO.isGlobal())
238       MOSymbol = AP.getSymbol(MO.getGlobal());
239     else if (MO.isCPI())
240       MOSymbol = AP.GetCPISymbol(MO.getIndex());
241     else if (MO.isJTI())
242       MOSymbol = AP.GetJTISymbol(MO.getIndex());
243     else
244       llvm_unreachable("Unknown operand type!");
245
246     StringRef SymbolName = MOSymbol->getName();
247     std::string LitaName = ".CONST_" + SymbolName.str();
248
249     MCSectionELF *Section = OutStreamer.getContext().getELFSection(
250         ".lita", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
251
252     OutStreamer.SwitchSection(Section);
253     Sym = AP.OutContext.getOrCreateSymbol(Twine(LitaName));
254     if (Sym->isUndefined()) {
255       OutStreamer.EmitLabel(Sym);
256       OutStreamer.EmitSymbolAttribute(Sym, MCSA_Local);
257       OutStreamer.EmitValue(Imm.getExpr(), AlignSize);
258       OutStreamer.EmitCodeAlignment(AlignSize);
259     }
260   }
261   return Sym;
262 }
263
264 void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
265                                                   const MachineInstr &MI) {
266   MCInst &MappedInst = static_cast <MCInst &>(Inst);
267   const MCRegisterInfo *RI = OutStreamer->getContext().getRegisterInfo();
268
269   switch (Inst.getOpcode()) {
270   default: return;
271
272   case Hexagon::A2_iconst: {
273     Inst.setOpcode(Hexagon::A2_addi);
274     MCOperand Reg = Inst.getOperand(0);
275     MCOperand S16 = Inst.getOperand(1);
276     HexagonMCInstrInfo::setMustNotExtend(*S16.getExpr());
277     HexagonMCInstrInfo::setS23_2_reloc(*S16.getExpr());
278     Inst.clear();
279     Inst.addOperand(Reg);
280     Inst.addOperand(MCOperand::createReg(Hexagon::R0));
281     Inst.addOperand(S16);
282     break;
283   }
284
285   // "$dst = CONST64(#$src1)",
286   case Hexagon::CONST64:
287     if (!OutStreamer->hasRawTextSupport()) {
288       const MCOperand &Imm = MappedInst.getOperand(1);
289       MCSectionSubPair Current = OutStreamer->getCurrentSection();
290
291       MCSymbol *Sym = smallData(*this, MI, *OutStreamer, Imm, 8);
292
293       OutStreamer->SwitchSection(Current.first, Current.second);
294       MCInst TmpInst;
295       MCOperand &Reg = MappedInst.getOperand(0);
296       TmpInst.setOpcode(Hexagon::L2_loadrdgp);
297       TmpInst.addOperand(Reg);
298       TmpInst.addOperand(MCOperand::createExpr(
299                          MCSymbolRefExpr::create(Sym, OutContext)));
300       MappedInst = TmpInst;
301
302     }
303     break;
304   case Hexagon::CONST32:
305     if (!OutStreamer->hasRawTextSupport()) {
306       MCOperand &Imm = MappedInst.getOperand(1);
307       MCSectionSubPair Current = OutStreamer->getCurrentSection();
308       MCSymbol *Sym = smallData(*this, MI, *OutStreamer, Imm, 4);
309       OutStreamer->SwitchSection(Current.first, Current.second);
310       MCInst TmpInst;
311       MCOperand &Reg = MappedInst.getOperand(0);
312       TmpInst.setOpcode(Hexagon::L2_loadrigp);
313       TmpInst.addOperand(Reg);
314       TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
315           MCSymbolRefExpr::create(Sym, OutContext), OutContext)));
316       MappedInst = TmpInst;
317     }
318     break;
319
320   // C2_pxfer_map maps to C2_or instruction. Though, it's possible to use
321   // C2_or during instruction selection itself but it results
322   // into suboptimal code.
323   case Hexagon::C2_pxfer_map: {
324     MCOperand &Ps = Inst.getOperand(1);
325     MappedInst.setOpcode(Hexagon::C2_or);
326     MappedInst.addOperand(Ps);
327     return;
328   }
329
330   // Vector reduce complex multiply by scalar, Rt & 1 map to :hi else :lo
331   // The insn is mapped from the 4 operand to the 3 operand raw form taking
332   // 3 register pairs.
333   case Hexagon::M2_vrcmpys_acc_s1: {
334     MCOperand &Rt = Inst.getOperand(3);
335     assert (Rt.isReg() && "Expected register and none was found");
336     unsigned Reg = RI->getEncodingValue(Rt.getReg());
337     if (Reg & 1)
338       MappedInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
339     else
340       MappedInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
341     Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI));
342     return;
343   }
344   case Hexagon::M2_vrcmpys_s1: {
345     MCOperand &Rt = Inst.getOperand(2);
346     assert (Rt.isReg() && "Expected register and none was found");
347     unsigned Reg = RI->getEncodingValue(Rt.getReg());
348     if (Reg & 1)
349       MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
350     else
351       MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
352     Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI));
353     return;
354   }
355
356   case Hexagon::M2_vrcmpys_s1rp: {
357     MCOperand &Rt = Inst.getOperand(2);
358     assert (Rt.isReg() && "Expected register and none was found");
359     unsigned Reg = RI->getEncodingValue(Rt.getReg());
360     if (Reg & 1)
361       MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
362     else
363       MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
364     Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI));
365     return;
366   }
367
368   case Hexagon::A4_boundscheck: {
369     MCOperand &Rs = Inst.getOperand(1);
370     assert (Rs.isReg() && "Expected register and none was found");
371     unsigned Reg = RI->getEncodingValue(Rs.getReg());
372     if (Reg & 1) // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
373       MappedInst.setOpcode(Hexagon::A4_boundscheck_hi);
374     else         // raw:lo
375       MappedInst.setOpcode(Hexagon::A4_boundscheck_lo);
376     Rs.setReg(getHexagonRegisterPair(Rs.getReg(), RI));
377     return;
378   }
379   case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
380     MCOperand &MO = MappedInst.getOperand(2);
381     int64_t Imm;
382     MCExpr const *Expr = MO.getExpr();
383     bool Success = Expr->evaluateAsAbsolute(Imm);
384     assert (Success && "Expected immediate and none was found");
385     (void)Success;
386     MCInst TmpInst;
387     if (Imm == 0) {
388       TmpInst.setOpcode(Hexagon::S2_vsathub);
389       TmpInst.addOperand(MappedInst.getOperand(0));
390       TmpInst.addOperand(MappedInst.getOperand(1));
391       MappedInst = TmpInst;
392       return;
393     }
394     TmpInst.setOpcode(Hexagon::S5_asrhub_rnd_sat);
395     TmpInst.addOperand(MappedInst.getOperand(0));
396     TmpInst.addOperand(MappedInst.getOperand(1));
397     const MCExpr *One = MCConstantExpr::create(1, OutContext);
398     const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext);
399     TmpInst.addOperand(
400         MCOperand::createExpr(HexagonMCExpr::create(Sub, OutContext)));
401     MappedInst = TmpInst;
402     return;
403   }
404   case Hexagon::S5_vasrhrnd_goodsyntax:
405   case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
406     MCOperand &MO2 = MappedInst.getOperand(2);
407     MCExpr const *Expr = MO2.getExpr();
408     int64_t Imm;
409     bool Success = Expr->evaluateAsAbsolute(Imm);
410     assert (Success && "Expected immediate and none was found");
411     (void)Success;
412     MCInst TmpInst;
413     if (Imm == 0) {
414       TmpInst.setOpcode(Hexagon::A2_combinew);
415       TmpInst.addOperand(MappedInst.getOperand(0));
416       MCOperand &MO1 = MappedInst.getOperand(1);
417       unsigned High = RI->getSubReg(MO1.getReg(), Hexagon::isub_hi);
418       unsigned Low = RI->getSubReg(MO1.getReg(), Hexagon::isub_lo);
419       // Add a new operand for the second register in the pair.
420       TmpInst.addOperand(MCOperand::createReg(High));
421       TmpInst.addOperand(MCOperand::createReg(Low));
422       MappedInst = TmpInst;
423       return;
424     }
425
426     if (Inst.getOpcode() == Hexagon::S2_asr_i_p_rnd_goodsyntax)
427       TmpInst.setOpcode(Hexagon::S2_asr_i_p_rnd);
428     else
429       TmpInst.setOpcode(Hexagon::S5_vasrhrnd);
430     TmpInst.addOperand(MappedInst.getOperand(0));
431     TmpInst.addOperand(MappedInst.getOperand(1));
432     const MCExpr *One = MCConstantExpr::create(1, OutContext);
433     const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext);
434     TmpInst.addOperand(
435         MCOperand::createExpr(HexagonMCExpr::create(Sub, OutContext)));
436     MappedInst = TmpInst;
437     return;
438   }
439   // if ("#u5==0") Assembler mapped to: "Rd=Rs"; else Rd=asr(Rs,#u5-1):rnd
440   case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
441     MCOperand &MO = Inst.getOperand(2);
442     MCExpr const *Expr = MO.getExpr();
443     int64_t Imm;
444     bool Success = Expr->evaluateAsAbsolute(Imm);
445     assert (Success && "Expected immediate and none was found");
446     (void)Success;
447     MCInst TmpInst;
448     if (Imm == 0) {
449       TmpInst.setOpcode(Hexagon::A2_tfr);
450       TmpInst.addOperand(MappedInst.getOperand(0));
451       TmpInst.addOperand(MappedInst.getOperand(1));
452       MappedInst = TmpInst;
453       return;
454     }
455     TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);
456     TmpInst.addOperand(MappedInst.getOperand(0));
457     TmpInst.addOperand(MappedInst.getOperand(1));
458     const MCExpr *One = MCConstantExpr::create(1, OutContext);
459     const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext);
460     TmpInst.addOperand(
461         MCOperand::createExpr(HexagonMCExpr::create(Sub, OutContext)));
462     MappedInst = TmpInst;
463     return;
464   }
465
466   // Translate a "$Rdd = #imm" to "$Rdd = combine(#[-1,0], #imm)"
467   case Hexagon::A2_tfrpi: {
468     MCInst TmpInst;
469     MCOperand &Rdd = MappedInst.getOperand(0);
470     MCOperand &MO = MappedInst.getOperand(1);
471
472     TmpInst.setOpcode(Hexagon::A2_combineii);
473     TmpInst.addOperand(Rdd);
474     int64_t Imm;
475     bool Success = MO.getExpr()->evaluateAsAbsolute(Imm);
476     if (Success && Imm < 0) {
477       const MCExpr *MOne = MCConstantExpr::create(-1, OutContext);
478       TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(MOne, OutContext)));
479     } else {
480       const MCExpr *Zero = MCConstantExpr::create(0, OutContext);
481       TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(Zero, OutContext)));
482     }
483     TmpInst.addOperand(MO);
484     MappedInst = TmpInst;
485     return;
486   }
487   // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
488   case Hexagon::A2_tfrp: {
489     MCOperand &MO = MappedInst.getOperand(1);
490     unsigned High = RI->getSubReg(MO.getReg(), Hexagon::isub_hi);
491     unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::isub_lo);
492     MO.setReg(High);
493     // Add a new operand for the second register in the pair.
494     MappedInst.addOperand(MCOperand::createReg(Low));
495     MappedInst.setOpcode(Hexagon::A2_combinew);
496     return;
497   }
498
499   case Hexagon::A2_tfrpt:
500   case Hexagon::A2_tfrpf: {
501     MCOperand &MO = MappedInst.getOperand(2);
502     unsigned High = RI->getSubReg(MO.getReg(), Hexagon::isub_hi);
503     unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::isub_lo);
504     MO.setReg(High);
505     // Add a new operand for the second register in the pair.
506     MappedInst.addOperand(MCOperand::createReg(Low));
507     MappedInst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
508                           ? Hexagon::C2_ccombinewt
509                           : Hexagon::C2_ccombinewf);
510     return;
511   }
512   case Hexagon::A2_tfrptnew:
513   case Hexagon::A2_tfrpfnew: {
514     MCOperand &MO = MappedInst.getOperand(2);
515     unsigned High = RI->getSubReg(MO.getReg(), Hexagon::isub_hi);
516     unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::isub_lo);
517     MO.setReg(High);
518     // Add a new operand for the second register in the pair.
519     MappedInst.addOperand(MCOperand::createReg(Low));
520     MappedInst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
521                           ? Hexagon::C2_ccombinewnewt
522                           : Hexagon::C2_ccombinewnewf);
523     return;
524   }
525
526   case Hexagon::M2_mpysmi: {
527     MCOperand &Imm = MappedInst.getOperand(2);
528     MCExpr const *Expr = Imm.getExpr();
529     int64_t Value;
530     bool Success = Expr->evaluateAsAbsolute(Value);
531     assert(Success);
532     (void)Success;
533     if (Value < 0 && Value > -256) {
534       MappedInst.setOpcode(Hexagon::M2_mpysin);
535       Imm.setExpr(HexagonMCExpr::create(
536           MCUnaryExpr::createMinus(Expr, OutContext), OutContext));
537     } else
538       MappedInst.setOpcode(Hexagon::M2_mpysip);
539     return;
540   }
541
542   case Hexagon::A2_addsp: {
543     MCOperand &Rt = Inst.getOperand(1);
544     assert (Rt.isReg() && "Expected register and none was found");
545     unsigned Reg = RI->getEncodingValue(Rt.getReg());
546     if (Reg & 1)
547       MappedInst.setOpcode(Hexagon::A2_addsph);
548     else
549       MappedInst.setOpcode(Hexagon::A2_addspl);
550     Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI));
551     return;
552   }
553   case Hexagon::V6_vd0:
554   case Hexagon::V6_vd0_128B: {
555     MCInst TmpInst;
556     assert (Inst.getOperand(0).isReg() &&
557             "Expected register and none was found");
558
559     TmpInst.setOpcode(Hexagon::V6_vxor);
560     TmpInst.addOperand(Inst.getOperand(0));
561     TmpInst.addOperand(Inst.getOperand(0));
562     TmpInst.addOperand(Inst.getOperand(0));
563     MappedInst = TmpInst;
564     return;
565   }
566
567   }
568 }
569
570
571 /// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to
572 /// the current output stream.
573 ///
574 void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
575   MCInst MCB = HexagonMCInstrInfo::createBundle();
576   const MCInstrInfo &MCII = *Subtarget->getInstrInfo();
577
578   if (MI->isBundle()) {
579     const MachineBasicBlock* MBB = MI->getParent();
580     MachineBasicBlock::const_instr_iterator MII = MI->getIterator();
581     unsigned IgnoreCount = 0;
582
583     for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII)
584       if (MII->getOpcode() == TargetOpcode::DBG_VALUE ||
585           MII->getOpcode() == TargetOpcode::IMPLICIT_DEF)
586         ++IgnoreCount;
587       else
588         HexagonLowerToMC(MCII, &*MII, MCB, *this);
589   }
590   else
591     HexagonLowerToMC(MCII, MI, MCB, *this);
592
593   bool Ok = HexagonMCInstrInfo::canonicalizePacket(
594       MCII, *Subtarget, OutStreamer->getContext(), MCB, nullptr);
595   assert(Ok);
596   (void)Ok;
597   if(HexagonMCInstrInfo::bundleSize(MCB) == 0)
598     return;
599   OutStreamer->EmitInstruction(MCB, getSubtargetInfo());
600 }
601
602 extern "C" void LLVMInitializeHexagonAsmPrinter() {
603   RegisterAsmPrinter<HexagonAsmPrinter> X(getTheHexagonTarget());
604 }