1 //===-- HexagonAsmPrinter.cpp - Print machine instrs to Hexagon assembly --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to Hexagon assembly language. This printer is
12 // the output mechanism used by `llc'.
14 //===----------------------------------------------------------------------===//
17 #include "HexagonAsmPrinter.h"
18 #include "HexagonMachineFunctionInfo.h"
19 #include "HexagonSubtarget.h"
20 #include "HexagonTargetMachine.h"
21 #include "MCTargetDesc/HexagonInstPrinter.h"
22 #include "MCTargetDesc/HexagonMCInstrInfo.h"
23 #include "MCTargetDesc/HexagonMCShuffler.h"
24 #include "llvm/ADT/StringExtras.h"
25 #include "llvm/Analysis/ConstantFolding.h"
26 #include "llvm/CodeGen/AsmPrinter.h"
27 #include "llvm/CodeGen/MachineFunctionPass.h"
28 #include "llvm/CodeGen/MachineInstr.h"
29 #include "llvm/CodeGen/MachineInstrBuilder.h"
30 #include "llvm/CodeGen/MachineModuleInfo.h"
31 #include "llvm/IR/Constants.h"
32 #include "llvm/IR/DataLayout.h"
33 #include "llvm/IR/DerivedTypes.h"
34 #include "llvm/IR/Mangler.h"
35 #include "llvm/IR/Module.h"
36 #include "llvm/MC/MCAsmInfo.h"
37 #include "llvm/MC/MCContext.h"
38 #include "llvm/MC/MCExpr.h"
39 #include "llvm/MC/MCInst.h"
40 #include "llvm/MC/MCSection.h"
41 #include "llvm/MC/MCSectionELF.h"
42 #include "llvm/MC/MCStreamer.h"
43 #include "llvm/MC/MCSymbol.h"
44 #include "llvm/Support/CommandLine.h"
45 #include "llvm/Support/Debug.h"
46 #include "llvm/Support/ELF.h"
47 #include "llvm/Support/Format.h"
48 #include "llvm/Support/MathExtras.h"
49 #include "llvm/Support/TargetRegistry.h"
50 #include "llvm/Support/raw_ostream.h"
51 #include "llvm/Target/TargetInstrInfo.h"
52 #include "llvm/Target/TargetLoweringObjectFile.h"
53 #include "llvm/Target/TargetOptions.h"
54 #include "llvm/Target/TargetRegisterInfo.h"
59 void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI,
60 MCInst &MCB, HexagonAsmPrinter &AP);
63 #define DEBUG_TYPE "asm-printer"
65 static cl::opt<bool> AlignCalls(
66 "hexagon-align-calls", cl::Hidden, cl::init(true),
67 cl::desc("Insert falign after call instruction for Hexagon target"));
69 // Given a scalar register return its pair.
70 inline static unsigned getHexagonRegisterPair(unsigned Reg,
71 const MCRegisterInfo *RI) {
72 assert(Hexagon::IntRegsRegClass.contains(Reg));
73 MCSuperRegIterator SR(Reg, RI, false);
75 assert(Hexagon::DoubleRegsRegClass.contains(Pair));
79 HexagonAsmPrinter::HexagonAsmPrinter(TargetMachine &TM,
80 std::unique_ptr<MCStreamer> Streamer)
81 : AsmPrinter(TM, std::move(Streamer)), Subtarget(nullptr) {}
83 void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
85 const MachineOperand &MO = MI->getOperand(OpNo);
87 switch (MO.getType()) {
88 default: llvm_unreachable ("<unknown operand type>");
89 case MachineOperand::MO_Register:
90 O << HexagonInstPrinter::getRegisterName(MO.getReg());
92 case MachineOperand::MO_Immediate:
95 case MachineOperand::MO_MachineBasicBlock:
96 MO.getMBB()->getSymbol()->print(O, MAI);
98 case MachineOperand::MO_ConstantPoolIndex:
99 GetCPISymbol(MO.getIndex())->print(O, MAI);
101 case MachineOperand::MO_GlobalAddress:
102 // Computing the address of a global symbol, not calling it.
103 getSymbol(MO.getGlobal())->print(O, MAI);
104 printOffset(MO.getOffset(), O);
110 // isBlockOnlyReachableByFallthrough - We need to override this since the
111 // default AsmPrinter does not print labels for any basic block that
112 // is only reachable by a fall through. That works for all cases except
113 // for the case in which the basic block is reachable by a fall through but
114 // through an indirect from a jump table. In this case, the jump table
115 // will contain a label not defined by AsmPrinter.
117 bool HexagonAsmPrinter::
118 isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
119 if (MBB->hasAddressTaken())
121 return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB);
125 /// PrintAsmOperand - Print out an operand for an inline asm expression.
127 bool HexagonAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
129 const char *ExtraCode,
131 // Does this asm operand have a single letter operand modifier?
132 if (ExtraCode && ExtraCode[0]) {
133 if (ExtraCode[1] != 0)
134 return true; // Unknown modifier.
136 switch (ExtraCode[0]) {
138 // See if this is a generic print operand
139 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, OS);
140 case 'c': // Don't print "$" before a global var name or constant.
141 // Hexagon never has a prefix.
142 printOperand(MI, OpNo, OS);
145 case 'H': { // The highest-numbered register of a pair.
146 const MachineOperand &MO = MI->getOperand(OpNo);
147 const MachineFunction &MF = *MI->getParent()->getParent();
148 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
151 unsigned RegNumber = MO.getReg();
152 // This should be an assert in the frontend.
153 if (Hexagon::DoubleRegsRegClass.contains(RegNumber))
154 RegNumber = TRI->getSubReg(RegNumber, ExtraCode[0] == 'L' ?
157 OS << HexagonInstPrinter::getRegisterName(RegNumber);
161 // Write 'i' if an integer constant, otherwise nothing. Used to print
163 if (MI->getOperand(OpNo).isImm())
169 printOperand(MI, OpNo, OS);
173 bool HexagonAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
174 unsigned OpNo, unsigned AsmVariant,
175 const char *ExtraCode,
177 if (ExtraCode && ExtraCode[0])
178 return true; // Unknown modifier.
180 const MachineOperand &Base = MI->getOperand(OpNo);
181 const MachineOperand &Offset = MI->getOperand(OpNo+1);
184 printOperand(MI, OpNo, O);
186 llvm_unreachable("Unimplemented");
188 if (Offset.isImm()) {
190 O << " + #" << Offset.getImm();
193 llvm_unreachable("Unimplemented");
198 static MCSymbol *smallData(AsmPrinter &AP, const MachineInstr &MI,
199 MCStreamer &OutStreamer, const MCOperand &Imm,
203 if (Imm.getExpr()->evaluateAsAbsolute(Value)) {
204 StringRef sectionPrefix;
205 std::string ImmString;
207 if (AlignSize == 8) {
208 Name = ".CONST_0000000000000000";
209 sectionPrefix = ".gnu.linkonce.l8";
210 ImmString = utohexstr(Value);
212 Name = ".CONST_00000000";
213 sectionPrefix = ".gnu.linkonce.l4";
214 ImmString = utohexstr(static_cast<uint32_t>(Value));
217 std::string symbolName = // Yes, leading zeros are kept.
218 Name.drop_back(ImmString.size()).str() + ImmString;
219 std::string sectionName = sectionPrefix.str() + symbolName;
221 MCSectionELF *Section = OutStreamer.getContext().getELFSection(
222 sectionName, ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
223 OutStreamer.SwitchSection(Section);
225 Sym = AP.OutContext.getOrCreateSymbol(Twine(symbolName));
226 if (Sym->isUndefined()) {
227 OutStreamer.EmitLabel(Sym);
228 OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global);
229 OutStreamer.EmitIntValue(Value, AlignSize);
230 OutStreamer.EmitCodeAlignment(AlignSize);
233 assert(Imm.isExpr() && "Expected expression and found none");
234 const MachineOperand &MO = MI.getOperand(1);
235 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
236 MCSymbol *MOSymbol = nullptr;
238 MOSymbol = AP.getSymbol(MO.getGlobal());
240 MOSymbol = AP.GetCPISymbol(MO.getIndex());
242 MOSymbol = AP.GetJTISymbol(MO.getIndex());
244 llvm_unreachable("Unknown operand type!");
246 StringRef SymbolName = MOSymbol->getName();
247 std::string LitaName = ".CONST_" + SymbolName.str();
249 MCSectionELF *Section = OutStreamer.getContext().getELFSection(
250 ".lita", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
252 OutStreamer.SwitchSection(Section);
253 Sym = AP.OutContext.getOrCreateSymbol(Twine(LitaName));
254 if (Sym->isUndefined()) {
255 OutStreamer.EmitLabel(Sym);
256 OutStreamer.EmitSymbolAttribute(Sym, MCSA_Local);
257 OutStreamer.EmitValue(Imm.getExpr(), AlignSize);
258 OutStreamer.EmitCodeAlignment(AlignSize);
264 static MCInst ScaleVectorOffset(MCInst &Inst, unsigned OpNo,
265 unsigned VectorSize, MCContext &Ctx) {
267 T.setOpcode(Inst.getOpcode());
268 for (unsigned i = 0, n = Inst.getNumOperands(); i != n; ++i) {
270 T.addOperand(Inst.getOperand(i));
273 MCOperand &ImmOp = Inst.getOperand(i);
274 const auto *HE = static_cast<const HexagonMCExpr*>(ImmOp.getExpr());
275 int32_t V = cast<MCConstantExpr>(HE->getExpr())->getValue();
276 auto *NewCE = MCConstantExpr::create(V / int32_t(VectorSize), Ctx);
277 auto *NewHE = HexagonMCExpr::create(NewCE, Ctx);
278 T.addOperand(MCOperand::createExpr(NewHE));
283 void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
284 const MachineInstr &MI) {
285 MCInst &MappedInst = static_cast <MCInst &>(Inst);
286 const MCRegisterInfo *RI = OutStreamer->getContext().getRegisterInfo();
287 const MachineFunction &MF = *MI.getParent()->getParent();
288 const auto &HST = MF.getSubtarget<HexagonSubtarget>();
289 const auto &VecRC = HST.useHVXSglOps() ? Hexagon::VectorRegsRegClass
290 : Hexagon::VectorRegs128BRegClass;
291 unsigned VectorSize = HST.getRegisterInfo()->getSpillSize(VecRC);
293 switch (Inst.getOpcode()) {
296 case Hexagon::A2_iconst: {
297 Inst.setOpcode(Hexagon::A2_addi);
298 MCOperand Reg = Inst.getOperand(0);
299 MCOperand S16 = Inst.getOperand(1);
300 HexagonMCInstrInfo::setMustNotExtend(*S16.getExpr());
301 HexagonMCInstrInfo::setS23_2_reloc(*S16.getExpr());
303 Inst.addOperand(Reg);
304 Inst.addOperand(MCOperand::createReg(Hexagon::R0));
305 Inst.addOperand(S16);
309 case Hexagon::A2_tfrf: {
310 Inst.setOpcode(Hexagon::A2_paddif);
311 Inst.addOperand(MCOperand::createExpr(MCConstantExpr::create(0, OutContext)));
315 case Hexagon::A2_tfrt: {
316 Inst.setOpcode(Hexagon::A2_paddit);
317 Inst.addOperand(MCOperand::createExpr(MCConstantExpr::create(0, OutContext)));
321 case Hexagon::A2_tfrfnew: {
322 Inst.setOpcode(Hexagon::A2_paddifnew);
323 Inst.addOperand(MCOperand::createExpr(MCConstantExpr::create(0, OutContext)));
327 case Hexagon::A2_tfrtnew: {
328 Inst.setOpcode(Hexagon::A2_padditnew);
329 Inst.addOperand(MCOperand::createExpr(MCConstantExpr::create(0, OutContext)));
333 case Hexagon::A2_zxtb: {
334 Inst.setOpcode(Hexagon::A2_andir);
335 Inst.addOperand(MCOperand::createExpr(MCConstantExpr::create(255, OutContext)));
339 // "$dst = CONST64(#$src1)",
340 case Hexagon::CONST64:
341 if (!OutStreamer->hasRawTextSupport()) {
342 const MCOperand &Imm = MappedInst.getOperand(1);
343 MCSectionSubPair Current = OutStreamer->getCurrentSection();
345 MCSymbol *Sym = smallData(*this, MI, *OutStreamer, Imm, 8);
347 OutStreamer->SwitchSection(Current.first, Current.second);
349 MCOperand &Reg = MappedInst.getOperand(0);
350 TmpInst.setOpcode(Hexagon::L2_loadrdgp);
351 TmpInst.addOperand(Reg);
352 TmpInst.addOperand(MCOperand::createExpr(
353 MCSymbolRefExpr::create(Sym, OutContext)));
354 MappedInst = TmpInst;
358 case Hexagon::CONST32:
359 if (!OutStreamer->hasRawTextSupport()) {
360 MCOperand &Imm = MappedInst.getOperand(1);
361 MCSectionSubPair Current = OutStreamer->getCurrentSection();
362 MCSymbol *Sym = smallData(*this, MI, *OutStreamer, Imm, 4);
363 OutStreamer->SwitchSection(Current.first, Current.second);
365 MCOperand &Reg = MappedInst.getOperand(0);
366 TmpInst.setOpcode(Hexagon::L2_loadrigp);
367 TmpInst.addOperand(Reg);
368 TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
369 MCSymbolRefExpr::create(Sym, OutContext), OutContext)));
370 MappedInst = TmpInst;
374 // C2_pxfer_map maps to C2_or instruction. Though, it's possible to use
375 // C2_or during instruction selection itself but it results
376 // into suboptimal code.
377 case Hexagon::C2_pxfer_map: {
378 MCOperand &Ps = Inst.getOperand(1);
379 MappedInst.setOpcode(Hexagon::C2_or);
380 MappedInst.addOperand(Ps);
384 // Vector reduce complex multiply by scalar, Rt & 1 map to :hi else :lo
385 // The insn is mapped from the 4 operand to the 3 operand raw form taking
387 case Hexagon::M2_vrcmpys_acc_s1: {
388 MCOperand &Rt = Inst.getOperand(3);
389 assert (Rt.isReg() && "Expected register and none was found");
390 unsigned Reg = RI->getEncodingValue(Rt.getReg());
392 MappedInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
394 MappedInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
395 Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI));
398 case Hexagon::M2_vrcmpys_s1: {
399 MCOperand &Rt = Inst.getOperand(2);
400 assert (Rt.isReg() && "Expected register and none was found");
401 unsigned Reg = RI->getEncodingValue(Rt.getReg());
403 MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
405 MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
406 Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI));
410 case Hexagon::M2_vrcmpys_s1rp: {
411 MCOperand &Rt = Inst.getOperand(2);
412 assert (Rt.isReg() && "Expected register and none was found");
413 unsigned Reg = RI->getEncodingValue(Rt.getReg());
415 MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
417 MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
418 Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI));
422 case Hexagon::A4_boundscheck: {
423 MCOperand &Rs = Inst.getOperand(1);
424 assert (Rs.isReg() && "Expected register and none was found");
425 unsigned Reg = RI->getEncodingValue(Rs.getReg());
426 if (Reg & 1) // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
427 MappedInst.setOpcode(Hexagon::A4_boundscheck_hi);
429 MappedInst.setOpcode(Hexagon::A4_boundscheck_lo);
430 Rs.setReg(getHexagonRegisterPair(Rs.getReg(), RI));
433 case Hexagon::PS_call_nr:
434 Inst.setOpcode(Hexagon::J2_call);
436 case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
437 MCOperand &MO = MappedInst.getOperand(2);
439 MCExpr const *Expr = MO.getExpr();
440 bool Success = Expr->evaluateAsAbsolute(Imm);
441 assert (Success && "Expected immediate and none was found");
445 TmpInst.setOpcode(Hexagon::S2_vsathub);
446 TmpInst.addOperand(MappedInst.getOperand(0));
447 TmpInst.addOperand(MappedInst.getOperand(1));
448 MappedInst = TmpInst;
451 TmpInst.setOpcode(Hexagon::S5_asrhub_rnd_sat);
452 TmpInst.addOperand(MappedInst.getOperand(0));
453 TmpInst.addOperand(MappedInst.getOperand(1));
454 const MCExpr *One = MCConstantExpr::create(1, OutContext);
455 const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext);
457 MCOperand::createExpr(HexagonMCExpr::create(Sub, OutContext)));
458 MappedInst = TmpInst;
461 case Hexagon::S5_vasrhrnd_goodsyntax:
462 case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
463 MCOperand &MO2 = MappedInst.getOperand(2);
464 MCExpr const *Expr = MO2.getExpr();
466 bool Success = Expr->evaluateAsAbsolute(Imm);
467 assert (Success && "Expected immediate and none was found");
471 TmpInst.setOpcode(Hexagon::A2_combinew);
472 TmpInst.addOperand(MappedInst.getOperand(0));
473 MCOperand &MO1 = MappedInst.getOperand(1);
474 unsigned High = RI->getSubReg(MO1.getReg(), Hexagon::isub_hi);
475 unsigned Low = RI->getSubReg(MO1.getReg(), Hexagon::isub_lo);
476 // Add a new operand for the second register in the pair.
477 TmpInst.addOperand(MCOperand::createReg(High));
478 TmpInst.addOperand(MCOperand::createReg(Low));
479 MappedInst = TmpInst;
483 if (Inst.getOpcode() == Hexagon::S2_asr_i_p_rnd_goodsyntax)
484 TmpInst.setOpcode(Hexagon::S2_asr_i_p_rnd);
486 TmpInst.setOpcode(Hexagon::S5_vasrhrnd);
487 TmpInst.addOperand(MappedInst.getOperand(0));
488 TmpInst.addOperand(MappedInst.getOperand(1));
489 const MCExpr *One = MCConstantExpr::create(1, OutContext);
490 const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext);
492 MCOperand::createExpr(HexagonMCExpr::create(Sub, OutContext)));
493 MappedInst = TmpInst;
496 // if ("#u5==0") Assembler mapped to: "Rd=Rs"; else Rd=asr(Rs,#u5-1):rnd
497 case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
498 MCOperand &MO = Inst.getOperand(2);
499 MCExpr const *Expr = MO.getExpr();
501 bool Success = Expr->evaluateAsAbsolute(Imm);
502 assert (Success && "Expected immediate and none was found");
506 TmpInst.setOpcode(Hexagon::A2_tfr);
507 TmpInst.addOperand(MappedInst.getOperand(0));
508 TmpInst.addOperand(MappedInst.getOperand(1));
509 MappedInst = TmpInst;
512 TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);
513 TmpInst.addOperand(MappedInst.getOperand(0));
514 TmpInst.addOperand(MappedInst.getOperand(1));
515 const MCExpr *One = MCConstantExpr::create(1, OutContext);
516 const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext);
518 MCOperand::createExpr(HexagonMCExpr::create(Sub, OutContext)));
519 MappedInst = TmpInst;
523 // Translate a "$Rdd = #imm" to "$Rdd = combine(#[-1,0], #imm)"
524 case Hexagon::A2_tfrpi: {
526 MCOperand &Rdd = MappedInst.getOperand(0);
527 MCOperand &MO = MappedInst.getOperand(1);
529 TmpInst.setOpcode(Hexagon::A2_combineii);
530 TmpInst.addOperand(Rdd);
532 bool Success = MO.getExpr()->evaluateAsAbsolute(Imm);
533 if (Success && Imm < 0) {
534 const MCExpr *MOne = MCConstantExpr::create(-1, OutContext);
535 TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(MOne, OutContext)));
537 const MCExpr *Zero = MCConstantExpr::create(0, OutContext);
538 TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(Zero, OutContext)));
540 TmpInst.addOperand(MO);
541 MappedInst = TmpInst;
544 // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
545 case Hexagon::A2_tfrp: {
546 MCOperand &MO = MappedInst.getOperand(1);
547 unsigned High = RI->getSubReg(MO.getReg(), Hexagon::isub_hi);
548 unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::isub_lo);
550 // Add a new operand for the second register in the pair.
551 MappedInst.addOperand(MCOperand::createReg(Low));
552 MappedInst.setOpcode(Hexagon::A2_combinew);
556 case Hexagon::A2_tfrpt:
557 case Hexagon::A2_tfrpf: {
558 MCOperand &MO = MappedInst.getOperand(2);
559 unsigned High = RI->getSubReg(MO.getReg(), Hexagon::isub_hi);
560 unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::isub_lo);
562 // Add a new operand for the second register in the pair.
563 MappedInst.addOperand(MCOperand::createReg(Low));
564 MappedInst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
565 ? Hexagon::C2_ccombinewt
566 : Hexagon::C2_ccombinewf);
569 case Hexagon::A2_tfrptnew:
570 case Hexagon::A2_tfrpfnew: {
571 MCOperand &MO = MappedInst.getOperand(2);
572 unsigned High = RI->getSubReg(MO.getReg(), Hexagon::isub_hi);
573 unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::isub_lo);
575 // Add a new operand for the second register in the pair.
576 MappedInst.addOperand(MCOperand::createReg(Low));
577 MappedInst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
578 ? Hexagon::C2_ccombinewnewt
579 : Hexagon::C2_ccombinewnewf);
583 case Hexagon::M2_mpysmi: {
584 MCOperand &Imm = MappedInst.getOperand(2);
585 MCExpr const *Expr = Imm.getExpr();
587 bool Success = Expr->evaluateAsAbsolute(Value);
590 if (Value < 0 && Value > -256) {
591 MappedInst.setOpcode(Hexagon::M2_mpysin);
592 Imm.setExpr(HexagonMCExpr::create(
593 MCUnaryExpr::createMinus(Expr, OutContext), OutContext));
595 MappedInst.setOpcode(Hexagon::M2_mpysip);
599 case Hexagon::A2_addsp: {
600 MCOperand &Rt = Inst.getOperand(1);
601 assert (Rt.isReg() && "Expected register and none was found");
602 unsigned Reg = RI->getEncodingValue(Rt.getReg());
604 MappedInst.setOpcode(Hexagon::A2_addsph);
606 MappedInst.setOpcode(Hexagon::A2_addspl);
607 Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI));
610 case Hexagon::V6_vd0:
611 case Hexagon::V6_vd0_128B: {
613 assert (Inst.getOperand(0).isReg() &&
614 "Expected register and none was found");
616 TmpInst.setOpcode(Hexagon::V6_vxor);
617 TmpInst.addOperand(Inst.getOperand(0));
618 TmpInst.addOperand(Inst.getOperand(0));
619 TmpInst.addOperand(Inst.getOperand(0));
620 MappedInst = TmpInst;
624 case Hexagon::V6_vL32Ub_pi:
625 case Hexagon::V6_vL32b_cur_pi:
626 case Hexagon::V6_vL32b_nt_cur_pi:
627 case Hexagon::V6_vL32b_pi:
628 case Hexagon::V6_vL32b_nt_pi:
629 case Hexagon::V6_vL32b_nt_tmp_pi:
630 case Hexagon::V6_vL32b_tmp_pi:
631 case Hexagon::V6_vL32Ub_pi_128B:
632 case Hexagon::V6_vL32b_cur_pi_128B:
633 case Hexagon::V6_vL32b_nt_cur_pi_128B:
634 case Hexagon::V6_vL32b_pi_128B:
635 case Hexagon::V6_vL32b_nt_pi_128B:
636 case Hexagon::V6_vL32b_nt_tmp_pi_128B:
637 case Hexagon::V6_vL32b_tmp_pi_128B:
638 MappedInst = ScaleVectorOffset(Inst, 3, VectorSize, OutContext);
641 case Hexagon::V6_vL32Ub_ai:
642 case Hexagon::V6_vL32b_ai:
643 case Hexagon::V6_vL32b_cur_ai:
644 case Hexagon::V6_vL32b_nt_ai:
645 case Hexagon::V6_vL32b_nt_cur_ai:
646 case Hexagon::V6_vL32b_nt_tmp_ai:
647 case Hexagon::V6_vL32b_tmp_ai:
648 case Hexagon::V6_vL32Ub_ai_128B:
649 case Hexagon::V6_vL32b_ai_128B:
650 case Hexagon::V6_vL32b_cur_ai_128B:
651 case Hexagon::V6_vL32b_nt_ai_128B:
652 case Hexagon::V6_vL32b_nt_cur_ai_128B:
653 case Hexagon::V6_vL32b_nt_tmp_ai_128B:
654 case Hexagon::V6_vL32b_tmp_ai_128B:
655 MappedInst = ScaleVectorOffset(Inst, 2, VectorSize, OutContext);
658 case Hexagon::V6_vS32Ub_pi:
659 case Hexagon::V6_vS32b_new_pi:
660 case Hexagon::V6_vS32b_nt_new_pi:
661 case Hexagon::V6_vS32b_nt_pi:
662 case Hexagon::V6_vS32b_pi:
663 case Hexagon::V6_vS32Ub_pi_128B:
664 case Hexagon::V6_vS32b_new_pi_128B:
665 case Hexagon::V6_vS32b_nt_new_pi_128B:
666 case Hexagon::V6_vS32b_nt_pi_128B:
667 case Hexagon::V6_vS32b_pi_128B:
668 MappedInst = ScaleVectorOffset(Inst, 2, VectorSize, OutContext);
671 case Hexagon::V6_vS32Ub_ai:
672 case Hexagon::V6_vS32b_ai:
673 case Hexagon::V6_vS32b_new_ai:
674 case Hexagon::V6_vS32b_nt_ai:
675 case Hexagon::V6_vS32b_nt_new_ai:
676 case Hexagon::V6_vS32Ub_ai_128B:
677 case Hexagon::V6_vS32b_ai_128B:
678 case Hexagon::V6_vS32b_new_ai_128B:
679 case Hexagon::V6_vS32b_nt_ai_128B:
680 case Hexagon::V6_vS32b_nt_new_ai_128B:
681 MappedInst = ScaleVectorOffset(Inst, 1, VectorSize, OutContext);
684 case Hexagon::V6_vL32b_cur_npred_pi:
685 case Hexagon::V6_vL32b_cur_pred_pi:
686 case Hexagon::V6_vL32b_npred_pi:
687 case Hexagon::V6_vL32b_nt_cur_npred_pi:
688 case Hexagon::V6_vL32b_nt_cur_pred_pi:
689 case Hexagon::V6_vL32b_nt_npred_pi:
690 case Hexagon::V6_vL32b_nt_pred_pi:
691 case Hexagon::V6_vL32b_nt_tmp_npred_pi:
692 case Hexagon::V6_vL32b_nt_tmp_pred_pi:
693 case Hexagon::V6_vL32b_pred_pi:
694 case Hexagon::V6_vL32b_tmp_npred_pi:
695 case Hexagon::V6_vL32b_tmp_pred_pi:
696 case Hexagon::V6_vL32b_cur_npred_pi_128B:
697 case Hexagon::V6_vL32b_cur_pred_pi_128B:
698 case Hexagon::V6_vL32b_npred_pi_128B:
699 case Hexagon::V6_vL32b_nt_cur_npred_pi_128B:
700 case Hexagon::V6_vL32b_nt_cur_pred_pi_128B:
701 case Hexagon::V6_vL32b_nt_npred_pi_128B:
702 case Hexagon::V6_vL32b_nt_pred_pi_128B:
703 case Hexagon::V6_vL32b_nt_tmp_npred_pi_128B:
704 case Hexagon::V6_vL32b_nt_tmp_pred_pi_128B:
705 case Hexagon::V6_vL32b_pred_pi_128B:
706 case Hexagon::V6_vL32b_tmp_npred_pi_128B:
707 case Hexagon::V6_vL32b_tmp_pred_pi_128B:
708 MappedInst = ScaleVectorOffset(Inst, 4, VectorSize, OutContext);
711 case Hexagon::V6_vL32b_cur_npred_ai:
712 case Hexagon::V6_vL32b_cur_pred_ai:
713 case Hexagon::V6_vL32b_npred_ai:
714 case Hexagon::V6_vL32b_nt_cur_npred_ai:
715 case Hexagon::V6_vL32b_nt_cur_pred_ai:
716 case Hexagon::V6_vL32b_nt_npred_ai:
717 case Hexagon::V6_vL32b_nt_pred_ai:
718 case Hexagon::V6_vL32b_nt_tmp_npred_ai:
719 case Hexagon::V6_vL32b_nt_tmp_pred_ai:
720 case Hexagon::V6_vL32b_pred_ai:
721 case Hexagon::V6_vL32b_tmp_npred_ai:
722 case Hexagon::V6_vL32b_tmp_pred_ai:
723 case Hexagon::V6_vL32b_cur_npred_ai_128B:
724 case Hexagon::V6_vL32b_cur_pred_ai_128B:
725 case Hexagon::V6_vL32b_npred_ai_128B:
726 case Hexagon::V6_vL32b_nt_cur_npred_ai_128B:
727 case Hexagon::V6_vL32b_nt_cur_pred_ai_128B:
728 case Hexagon::V6_vL32b_nt_npred_ai_128B:
729 case Hexagon::V6_vL32b_nt_pred_ai_128B:
730 case Hexagon::V6_vL32b_nt_tmp_npred_ai_128B:
731 case Hexagon::V6_vL32b_nt_tmp_pred_ai_128B:
732 case Hexagon::V6_vL32b_pred_ai_128B:
733 case Hexagon::V6_vL32b_tmp_npred_ai_128B:
734 case Hexagon::V6_vL32b_tmp_pred_ai_128B:
735 MappedInst = ScaleVectorOffset(Inst, 3, VectorSize, OutContext);
738 case Hexagon::V6_vS32Ub_npred_pi:
739 case Hexagon::V6_vS32Ub_pred_pi:
740 case Hexagon::V6_vS32b_new_npred_pi:
741 case Hexagon::V6_vS32b_new_pred_pi:
742 case Hexagon::V6_vS32b_npred_pi:
743 case Hexagon::V6_vS32b_nqpred_pi:
744 case Hexagon::V6_vS32b_nt_new_npred_pi:
745 case Hexagon::V6_vS32b_nt_new_pred_pi:
746 case Hexagon::V6_vS32b_nt_npred_pi:
747 case Hexagon::V6_vS32b_nt_nqpred_pi:
748 case Hexagon::V6_vS32b_nt_pred_pi:
749 case Hexagon::V6_vS32b_nt_qpred_pi:
750 case Hexagon::V6_vS32b_pred_pi:
751 case Hexagon::V6_vS32b_qpred_pi:
752 case Hexagon::V6_vS32Ub_npred_pi_128B:
753 case Hexagon::V6_vS32Ub_pred_pi_128B:
754 case Hexagon::V6_vS32b_new_npred_pi_128B:
755 case Hexagon::V6_vS32b_new_pred_pi_128B:
756 case Hexagon::V6_vS32b_npred_pi_128B:
757 case Hexagon::V6_vS32b_nqpred_pi_128B:
758 case Hexagon::V6_vS32b_nt_new_npred_pi_128B:
759 case Hexagon::V6_vS32b_nt_new_pred_pi_128B:
760 case Hexagon::V6_vS32b_nt_npred_pi_128B:
761 case Hexagon::V6_vS32b_nt_nqpred_pi_128B:
762 case Hexagon::V6_vS32b_nt_pred_pi_128B:
763 case Hexagon::V6_vS32b_nt_qpred_pi_128B:
764 case Hexagon::V6_vS32b_pred_pi_128B:
765 case Hexagon::V6_vS32b_qpred_pi_128B:
766 MappedInst = ScaleVectorOffset(Inst, 3, VectorSize, OutContext);
769 case Hexagon::V6_vS32Ub_npred_ai:
770 case Hexagon::V6_vS32Ub_pred_ai:
771 case Hexagon::V6_vS32b_new_npred_ai:
772 case Hexagon::V6_vS32b_new_pred_ai:
773 case Hexagon::V6_vS32b_npred_ai:
774 case Hexagon::V6_vS32b_nqpred_ai:
775 case Hexagon::V6_vS32b_nt_new_npred_ai:
776 case Hexagon::V6_vS32b_nt_new_pred_ai:
777 case Hexagon::V6_vS32b_nt_npred_ai:
778 case Hexagon::V6_vS32b_nt_nqpred_ai:
779 case Hexagon::V6_vS32b_nt_pred_ai:
780 case Hexagon::V6_vS32b_nt_qpred_ai:
781 case Hexagon::V6_vS32b_pred_ai:
782 case Hexagon::V6_vS32b_qpred_ai:
783 case Hexagon::V6_vS32Ub_npred_ai_128B:
784 case Hexagon::V6_vS32Ub_pred_ai_128B:
785 case Hexagon::V6_vS32b_new_npred_ai_128B:
786 case Hexagon::V6_vS32b_new_pred_ai_128B:
787 case Hexagon::V6_vS32b_npred_ai_128B:
788 case Hexagon::V6_vS32b_nqpred_ai_128B:
789 case Hexagon::V6_vS32b_nt_new_npred_ai_128B:
790 case Hexagon::V6_vS32b_nt_new_pred_ai_128B:
791 case Hexagon::V6_vS32b_nt_npred_ai_128B:
792 case Hexagon::V6_vS32b_nt_nqpred_ai_128B:
793 case Hexagon::V6_vS32b_nt_pred_ai_128B:
794 case Hexagon::V6_vS32b_nt_qpred_ai_128B:
795 case Hexagon::V6_vS32b_pred_ai_128B:
796 case Hexagon::V6_vS32b_qpred_ai_128B:
797 MappedInst = ScaleVectorOffset(Inst, 2, VectorSize, OutContext);
803 /// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to
804 /// the current output stream.
806 void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
807 MCInst MCB = HexagonMCInstrInfo::createBundle();
808 const MCInstrInfo &MCII = *Subtarget->getInstrInfo();
810 if (MI->isBundle()) {
811 const MachineBasicBlock* MBB = MI->getParent();
812 MachineBasicBlock::const_instr_iterator MII = MI->getIterator();
814 for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII)
815 if (!MII->isDebugValue() && !MII->isImplicitDef())
816 HexagonLowerToMC(MCII, &*MII, MCB, *this);
819 HexagonLowerToMC(MCII, MI, MCB, *this);
821 bool Ok = HexagonMCInstrInfo::canonicalizePacket(
822 MCII, *Subtarget, OutStreamer->getContext(), MCB, nullptr);
825 if(HexagonMCInstrInfo::bundleSize(MCB) == 0)
827 OutStreamer->EmitInstruction(MCB, getSubtargetInfo());
830 extern "C" void LLVMInitializeHexagonAsmPrinter() {
831 RegisterAsmPrinter<HexagonAsmPrinter> X(getTheHexagonTarget());