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