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