Go to the documentation of this file.
63 #define DEBUG_TYPE "asm-printer"
115 const char *ExtraCode,
118 if (ExtraCode && ExtraCode[0]) {
119 if (ExtraCode[1] != 0)
122 switch (ExtraCode[0]) {
135 if (Hexagon::DoubleRegsRegClass.
contains(RegNumber))
136 RegNumber =
TRI->
getSubReg(RegNumber, ExtraCode[0] ==
'L' ?
145 if (
MI->getOperand(OpNo).isImm())
157 const char *ExtraCode,
159 if (ExtraCode && ExtraCode[0])
170 if (Offset.isImm()) {
172 O <<
"+#" << Offset.getImm();
185 if (
Imm.getExpr()->evaluateAsAbsolute(
Value)) {
187 std::string ImmString;
189 if (AlignSize == 8) {
190 Name =
".CONST_0000000000000000";
191 sectionPrefix =
".gnu.linkonce.l8";
192 ImmString = utohexstr(
Value);
194 Name =
".CONST_00000000";
195 sectionPrefix =
".gnu.linkonce.l4";
199 std::string symbolName =
200 Name.drop_back(ImmString.size()).str() + ImmString;
201 std::string sectionName = sectionPrefix.
str() + symbolName;
215 assert(
Imm.isExpr() &&
"Expected expression and found none");
229 std::string LitaName =
".CONST_" +
SymbolName.str();
257 int32_t V = cast<MCConstantExpr>(HE->getExpr())->getValue();
271 unsigned VectorSize = HRI.getRegSizeInBits(Hexagon::HvxVRRegClass) / 8;
277 case Hexagon::A2_iconst: {
290 case Hexagon::A2_tfrf: {
297 case Hexagon::A2_tfrt: {
304 case Hexagon::A2_tfrfnew: {
311 case Hexagon::A2_tfrtnew: {
318 case Hexagon::A2_zxtb: {
326 case Hexagon::CONST64:
334 OutStreamer->SwitchSection(Current.first, Current.second);
341 MappedInst = TmpInst;
351 OutStreamer->SwitchSection(Current.first, Current.second);
358 MappedInst = TmpInst;
365 case Hexagon::C2_pxfer_map: {
375 case Hexagon::M2_vrcmpys_acc_s1: {
377 assert(Rt.
isReg() &&
"Expected register and none was found");
380 MappedInst.
setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
382 MappedInst.
setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
386 case Hexagon::M2_vrcmpys_s1: {
388 assert(Rt.
isReg() &&
"Expected register and none was found");
391 MappedInst.
setOpcode(Hexagon::M2_vrcmpys_s1_h);
393 MappedInst.
setOpcode(Hexagon::M2_vrcmpys_s1_l);
398 case Hexagon::M2_vrcmpys_s1rp: {
400 assert(Rt.
isReg() &&
"Expected register and none was found");
403 MappedInst.
setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
405 MappedInst.
setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
410 case Hexagon::A4_boundscheck: {
412 assert(Rs.
isReg() &&
"Expected register and none was found");
415 MappedInst.
setOpcode(Hexagon::A4_boundscheck_hi);
417 MappedInst.
setOpcode(Hexagon::A4_boundscheck_lo);
422 case Hexagon::PS_call_nr:
426 case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
438 MappedInst = TmpInst;
441 TmpInst.
setOpcode(Hexagon::S5_asrhub_rnd_sat);
448 MappedInst = TmpInst;
452 case Hexagon::S5_vasrhrnd_goodsyntax:
453 case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
470 MappedInst = TmpInst;
474 if (Inst.
getOpcode() == Hexagon::S2_asr_i_p_rnd_goodsyntax)
475 TmpInst.
setOpcode(Hexagon::S2_asr_i_p_rnd);
484 MappedInst = TmpInst;
489 case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
501 MappedInst = TmpInst;
504 TmpInst.
setOpcode(Hexagon::S2_asr_i_r_rnd);
511 MappedInst = TmpInst;
516 case Hexagon::A2_tfrpi: {
521 TmpInst.
setOpcode(Hexagon::A2_combineii);
535 MappedInst = TmpInst;
540 case Hexagon::A2_tfrp: {
547 MappedInst.
setOpcode(Hexagon::A2_combinew);
551 case Hexagon::A2_tfrpt:
552 case Hexagon::A2_tfrpf: {
560 ? Hexagon::C2_ccombinewt
561 : Hexagon::C2_ccombinewf);
565 case Hexagon::A2_tfrptnew:
566 case Hexagon::A2_tfrpfnew: {
574 ? Hexagon::C2_ccombinewnewt
575 : Hexagon::C2_ccombinewnewf);
579 case Hexagon::M2_mpysmi: {
587 MappedInst.
setOpcode(Hexagon::M2_mpysin);
591 MappedInst.
setOpcode(Hexagon::M2_mpysip);
595 case Hexagon::A2_addsp: {
597 assert(Rt.
isReg() &&
"Expected register and none was found");
600 MappedInst.
setOpcode(Hexagon::A2_addsph);
602 MappedInst.
setOpcode(Hexagon::A2_addspl);
607 case Hexagon::V6_vd0: {
610 "Expected register and none was found");
616 MappedInst = TmpInst;
620 case Hexagon::V6_vdd0: {
623 "Expected register and none was found");
629 MappedInst = TmpInst;
633 case Hexagon::V6_vL32Ub_pi:
634 case Hexagon::V6_vL32b_cur_pi:
635 case Hexagon::V6_vL32b_nt_cur_pi:
636 case Hexagon::V6_vL32b_pi:
637 case Hexagon::V6_vL32b_nt_pi:
638 case Hexagon::V6_vL32b_nt_tmp_pi:
639 case Hexagon::V6_vL32b_tmp_pi:
643 case Hexagon::V6_vL32Ub_ai:
644 case Hexagon::V6_vL32b_ai:
645 case Hexagon::V6_vL32b_cur_ai:
646 case Hexagon::V6_vL32b_nt_ai:
647 case Hexagon::V6_vL32b_nt_cur_ai:
648 case Hexagon::V6_vL32b_nt_tmp_ai:
649 case Hexagon::V6_vL32b_tmp_ai:
653 case Hexagon::V6_vS32Ub_pi:
654 case Hexagon::V6_vS32b_new_pi:
655 case Hexagon::V6_vS32b_nt_new_pi:
656 case Hexagon::V6_vS32b_nt_pi:
657 case Hexagon::V6_vS32b_pi:
661 case Hexagon::V6_vS32Ub_ai:
662 case Hexagon::V6_vS32b_ai:
663 case Hexagon::V6_vS32b_new_ai:
664 case Hexagon::V6_vS32b_nt_ai:
665 case Hexagon::V6_vS32b_nt_new_ai:
669 case Hexagon::V6_vL32b_cur_npred_pi:
670 case Hexagon::V6_vL32b_cur_pred_pi:
671 case Hexagon::V6_vL32b_npred_pi:
672 case Hexagon::V6_vL32b_nt_cur_npred_pi:
673 case Hexagon::V6_vL32b_nt_cur_pred_pi:
674 case Hexagon::V6_vL32b_nt_npred_pi:
675 case Hexagon::V6_vL32b_nt_pred_pi:
676 case Hexagon::V6_vL32b_nt_tmp_npred_pi:
677 case Hexagon::V6_vL32b_nt_tmp_pred_pi:
678 case Hexagon::V6_vL32b_pred_pi:
679 case Hexagon::V6_vL32b_tmp_npred_pi:
680 case Hexagon::V6_vL32b_tmp_pred_pi:
684 case Hexagon::V6_vL32b_cur_npred_ai:
685 case Hexagon::V6_vL32b_cur_pred_ai:
686 case Hexagon::V6_vL32b_npred_ai:
687 case Hexagon::V6_vL32b_nt_cur_npred_ai:
688 case Hexagon::V6_vL32b_nt_cur_pred_ai:
689 case Hexagon::V6_vL32b_nt_npred_ai:
690 case Hexagon::V6_vL32b_nt_pred_ai:
691 case Hexagon::V6_vL32b_nt_tmp_npred_ai:
692 case Hexagon::V6_vL32b_nt_tmp_pred_ai:
693 case Hexagon::V6_vL32b_pred_ai:
694 case Hexagon::V6_vL32b_tmp_npred_ai:
695 case Hexagon::V6_vL32b_tmp_pred_ai:
699 case Hexagon::V6_vS32Ub_npred_pi:
700 case Hexagon::V6_vS32Ub_pred_pi:
701 case Hexagon::V6_vS32b_new_npred_pi:
702 case Hexagon::V6_vS32b_new_pred_pi:
703 case Hexagon::V6_vS32b_npred_pi:
704 case Hexagon::V6_vS32b_nqpred_pi:
705 case Hexagon::V6_vS32b_nt_new_npred_pi:
706 case Hexagon::V6_vS32b_nt_new_pred_pi:
707 case Hexagon::V6_vS32b_nt_npred_pi:
708 case Hexagon::V6_vS32b_nt_nqpred_pi:
709 case Hexagon::V6_vS32b_nt_pred_pi:
710 case Hexagon::V6_vS32b_nt_qpred_pi:
711 case Hexagon::V6_vS32b_pred_pi:
712 case Hexagon::V6_vS32b_qpred_pi:
716 case Hexagon::V6_vS32Ub_npred_ai:
717 case Hexagon::V6_vS32Ub_pred_ai:
718 case Hexagon::V6_vS32b_new_npred_ai:
719 case Hexagon::V6_vS32b_new_pred_ai:
720 case Hexagon::V6_vS32b_npred_ai:
721 case Hexagon::V6_vS32b_nqpred_ai:
722 case Hexagon::V6_vS32b_nt_new_npred_ai:
723 case Hexagon::V6_vS32b_nt_new_pred_ai:
724 case Hexagon::V6_vS32b_nt_npred_ai:
725 case Hexagon::V6_vS32b_nt_nqpred_ai:
726 case Hexagon::V6_vS32b_nt_pred_ai:
727 case Hexagon::V6_vS32b_nt_qpred_ai:
728 case Hexagon::V6_vS32b_pred_ai:
729 case Hexagon::V6_vS32b_qpred_ai:
734 case Hexagon::V6_vS32b_srls_ai:
738 case Hexagon::V6_vS32b_srls_pi:
751 if (
MI->isBundle()) {
755 for (++MII; MII !=
MBB->
instr_end() && MII->isInsideBundle(); ++MII)
756 if (!MII->isDebugInstr() && !MII->isImplicitDef())
764 if (
MI->isBundle() && HII.getBundleNoShuf(*
MI))
777 static const int8_t NoopsInSledCount = 4;
811 SledJumpPacket.
setOpcode(Hexagon::BUNDLE);
@ MO_Immediate
Immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void setMustNotExtend(MCExpr const &Expr, bool Val=true)
static MCOperand createExpr(const MCExpr *Val)
void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind, uint8_t Version=0)
const GlobalValue * getGlobal() const
static MCOperand createImm(int64_t Val)
Context object for machine code objects.
static MCSymbol * smallData(AsmPrinter &AP, const MachineInstr &MI, MCStreamer &OutStreamer, const MCOperand &Imm, int AlignSize, const MCSubtargetInfo &STI)
const MCAsmInfo * MAI
Target Asm Printer information.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
return AArch64::GPR64RegClass contains(Reg)
static const MCUnaryExpr * createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
Reg
All possible values of the reg field in the ModR/M byte.
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
uint16_t getEncodingValue(MCRegister RegNo) const
Returns the encoding for RegNo.
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)
Print the MachineOperand as a symbol.
Instances of this class represent a single low-level machine instruction.
This represents a section on linux, lots of unix variants and some bare metal systems.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override
PrintAsmOperand - Print out an operand for an inline asm expression.
unsigned getNumOperands() const
unsigned const TargetRegisterInfo * TRI
@ MO_Register
Register operand.
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
static const char * getRegisterName(unsigned RegNo)
void setOpcode(unsigned Op)
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
Streaming machine code generation interface.
void setS27_2_reloc(MCExpr const &Expr, bool Val=true)
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI, MCInst &MCB, HexagonAsmPrinter &AP)
@ MO_GlobalAddress
Address of a global value.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void setMemReorderDisabled(MCInst &MCI)
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
static HexagonMCExpr * create(MCExpr const *Expr, MCContext &Ctx)
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
void EmitSled(const MachineInstr &MI, SledKind Kind)
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const
Return true if the basic block has exactly one predecessor and the control transfer mechanism between...
MachineOperand class - Representation of each machine instruction operand.
This class implements an extremely fast bulk output stream that can only output to a stream.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
StringRef getName() const
getName - Get the symbol name.
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
size_t bundleSize(MCInst const &MCI)
void emitInstruction(const MachineInstr *MI) override
Print out a single Hexagon MI to the current output stream.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static MCOperand createInst(const MCInst *Val)
void addOperand(const MCOperand Op)
const HexagonInstrInfo * getInstrInfo() const override
static unsigned getHexagonRegisterPair(unsigned Reg, const MCRegisterInfo *RI)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
bool hasAddressTaken() const
Test whether this block is potentially the target of an indirect branch.
#define LLVM_EXTERNAL_VISIBILITY
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
void HexagonProcessInstruction(MCInst &Inst, const MachineInstr &MBB)
bool canonicalizePacket(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCContext &Context, MCInst &MCB, HexagonMCChecker *Checker, bool AttemptCompatibility=false)
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCSymbol * getSymbol(const GlobalValue *GV) const
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
MachineFunction * MF
The current machine function.
MCContext & OutContext
This is the context for the output file that we are streaming.
MCSuperRegIterator enumerates all super-registers of Reg.
bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const override
Return true if the basic block has exactly one predecessor and the control transfer mechanism between...
Register getReg() const
getReg - Returns the register number.
static MCInst ScaleVectorOffset(MCInst &Inst, unsigned OpNo, unsigned VectorSize, MCContext &Ctx)
instr_iterator instr_end()
Target & getTheHexagonTarget()
MachineBasicBlock * getMBB() const
StringRef - Represent a constant reference to a string, i.e.
MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const
Return the symbol for the specified jump table entry.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static MCOperand createReg(unsigned Reg)
@ MO_MachineBasicBlock
MachineBasicBlock reference.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Wrapper class representing virtual and physical registers.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Interface to description of machine instruction set.
void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI)
void emitNops(unsigned N)
Emit N NOP instructions.
virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
Iterator for intrusive lists based on ilist_node.
const MCExpr * getExpr() const
unsigned getOpcode() const
This class is intended to be used as a driving class for all asm writers.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
@ MCSA_Global
.type _foo, @gnu_unique_object
void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI)
MCContext & getContext() const
virtual void emitCodeAlignment(unsigned ByteAlignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit=0)
Emit nops until the byte alignment ByteAlignment is reached.
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonAsmPrinter()
const MCOperand & getOperand(unsigned i) const
std::pair< MCSection *, const MCExpr * > MCSectionSubPair
void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI)
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Instances of this class represent operands of the MCInst class.
void setReg(unsigned Reg)
Set the register number.
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...
The same transformation can work with an even modulo with the addition of a and shrink the compare RHS by the same amount Unless the target supports that transformation probably isn t worthwhile The transformation can also easily be made to work with non zero equality for n
virtual void SwitchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
Generic base class for all target subtargets.
LLVM Value Representation.
Base class for the full range of assembler expressions which are needed for parsing.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
unsigned getReg() const
Returns the register number.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.