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