Optional<MCOperand> X86MCInstLower::LowerMachineOperand(const MachineInstr *MI, const MachineOperand &MO) const { switch (MO.getType()) { default: MI->dump(); llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: // Ignore all implicit register operands. if (MO.isImplicit()) return None; return MCOperand::createReg(MO.getReg()); case MachineOperand::MO_Immediate: return MCOperand::createImm(MO.getImm()); case MachineOperand::MO_MachineBasicBlock: case MachineOperand::MO_GlobalAddress: case MachineOperand::MO_ExternalSymbol: return LowerSymbolOperand(MO, GetSymbolFromOperand(MO)); case MachineOperand::MO_MCSymbol: return LowerSymbolOperand(MO, MO.getMCSymbol()); case MachineOperand::MO_JumpTableIndex: return LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex())); case MachineOperand::MO_ConstantPoolIndex: return LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex())); case MachineOperand::MO_BlockAddress: return LowerSymbolOperand( MO, AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress())); case MachineOperand::MO_RegisterMask: // Ignore call clobbers. return None; } }
/// isIdenticalTo - Return true if this operand is identical to the specified /// operand. bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { if (getType() != Other.getType() || getTargetFlags() != Other.getTargetFlags()) return false; switch (getType()) { default: llvm_unreachable("Unrecognized operand type"); case MachineOperand::MO_Register: return getReg() == Other.getReg() && isDef() == Other.isDef() && getSubReg() == Other.getSubReg(); case MachineOperand::MO_Immediate: return getImm() == Other.getImm(); case MachineOperand::MO_FPImmediate: return getFPImm() == Other.getFPImm(); case MachineOperand::MO_MachineBasicBlock: return getMBB() == Other.getMBB(); case MachineOperand::MO_FrameIndex: return getIndex() == Other.getIndex(); case MachineOperand::MO_ConstantPoolIndex: return getIndex() == Other.getIndex() && getOffset() == Other.getOffset(); case MachineOperand::MO_JumpTableIndex: return getIndex() == Other.getIndex(); case MachineOperand::MO_GlobalAddress: return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); case MachineOperand::MO_ExternalSymbol: return !strcmp(getSymbolName(), Other.getSymbolName()) && getOffset() == Other.getOffset(); case MachineOperand::MO_BlockAddress: return getBlockAddress() == Other.getBlockAddress(); } }
MCOperand Cpu0MCInstLower::LowerSymbolOperand(const MachineOperand &MO, MachineOperandType MOTy, unsigned Offset) const { MCSymbolRefExpr::VariantKind Kind; const MCSymbol *Symbol; switch(MO.getTargetFlags()) { default: llvm_unreachable("Invalid target flag!"); case Cpu0II::MO_NO_FLAG: Kind = MCSymbolRefExpr::VK_None; break; // Cpu0_GPREL is for llc -march=cpu0 -relocation-model=static -cpu0-islinux- // format=false (global var in .sdata). case Cpu0II::MO_GPREL: Kind = MCSymbolRefExpr::VK_Cpu0_GPREL; break; case Cpu0II::MO_GOT_CALL: Kind = MCSymbolRefExpr::VK_Cpu0_GOT_CALL; break; case Cpu0II::MO_GOT16: Kind = MCSymbolRefExpr::VK_Cpu0_GOT16; break; case Cpu0II::MO_GOT: Kind = MCSymbolRefExpr::VK_Cpu0_GOT; break; // ABS_HI and ABS_LO is for llc -march=cpu0 -relocation-model=static (global // var in .data). case Cpu0II::MO_ABS_HI: Kind = MCSymbolRefExpr::VK_Cpu0_ABS_HI; break; case Cpu0II::MO_ABS_LO: Kind = MCSymbolRefExpr::VK_Cpu0_ABS_LO; break; case Cpu0II::MO_GOT_HI16: Kind = MCSymbolRefExpr::VK_Cpu0_GOT_HI16; break; case Cpu0II::MO_GOT_LO16: Kind = MCSymbolRefExpr::VK_Cpu0_GOT_LO16; break; } switch (MOTy) { case MachineOperand::MO_MachineBasicBlock: Symbol = MO.getMBB()->getSymbol(); break; case MachineOperand::MO_GlobalAddress: Symbol = Mang->getSymbol(MO.getGlobal()); break; case MachineOperand::MO_BlockAddress: Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()); Offset += MO.getOffset(); break; case MachineOperand::MO_ExternalSymbol: Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName()); Offset += MO.getOffset(); break; default: llvm_unreachable("<unknown operand type>"); } const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, Kind, *Ctx); if (!Offset) return MCOperand::CreateExpr(MCSym); // Assume offset is never negative. assert(Offset > 0); const MCConstantExpr *OffsetExpr = MCConstantExpr::Create(Offset, *Ctx); const MCBinaryExpr *AddExpr = MCBinaryExpr::CreateAdd(MCSym, OffsetExpr, *Ctx); return MCOperand::CreateExpr(AddExpr); }
MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO, MachineOperandType MOTy, unsigned Offset) const { MipsMCSymbolRefExpr::VariantKind Kind; const MCSymbol *Symbol; switch(MO.getTargetFlags()) { default: assert(0 && "Invalid target flag!"); case MipsII::MO_NO_FLAG: Kind = MipsMCSymbolRefExpr::VK_Mips_None; break; case MipsII::MO_GPREL: Kind = MipsMCSymbolRefExpr::VK_Mips_GPREL; break; case MipsII::MO_GOT_CALL: Kind = MipsMCSymbolRefExpr::VK_Mips_GOT_CALL; break; case MipsII::MO_GOT: Kind = MipsMCSymbolRefExpr::VK_Mips_GOT; break; case MipsII::MO_ABS_HI: Kind = MipsMCSymbolRefExpr::VK_Mips_ABS_HI; break; case MipsII::MO_ABS_LO: Kind = MipsMCSymbolRefExpr::VK_Mips_ABS_LO; break; case MipsII::MO_TLSGD: Kind = MipsMCSymbolRefExpr::VK_Mips_TLSGD; break; case MipsII::MO_GOTTPREL: Kind = MipsMCSymbolRefExpr::VK_Mips_GOTTPREL; break; case MipsII::MO_TPREL_HI: Kind = MipsMCSymbolRefExpr::VK_Mips_TPREL_HI; break; case MipsII::MO_TPREL_LO: Kind = MipsMCSymbolRefExpr::VK_Mips_TPREL_LO; break; case MipsII::MO_GPOFF_HI: Kind = MipsMCSymbolRefExpr::VK_Mips_GPOFF_HI; break; case MipsII::MO_GPOFF_LO: Kind = MipsMCSymbolRefExpr::VK_Mips_GPOFF_LO; break; case MipsII::MO_GOT_DISP: Kind = MipsMCSymbolRefExpr::VK_Mips_GOT_DISP; break; case MipsII::MO_GOT_PAGE: Kind = MipsMCSymbolRefExpr::VK_Mips_GOT_PAGE; break; case MipsII::MO_GOT_OFST: Kind = MipsMCSymbolRefExpr::VK_Mips_GOT_OFST; break; } switch (MOTy) { case MachineOperand::MO_MachineBasicBlock: Symbol = MO.getMBB()->getSymbol(); break; case MachineOperand::MO_GlobalAddress: Symbol = Mang->getSymbol(MO.getGlobal()); break; case MachineOperand::MO_BlockAddress: Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()); break; case MachineOperand::MO_ExternalSymbol: Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName()); break; case MachineOperand::MO_JumpTableIndex: Symbol = AsmPrinter.GetJTISymbol(MO.getIndex()); break; case MachineOperand::MO_ConstantPoolIndex: Symbol = AsmPrinter.GetCPISymbol(MO.getIndex()); if (MO.getOffset()) Offset += MO.getOffset(); break; default: llvm_unreachable("<unknown operand type>"); } return MCOperand::CreateExpr(MipsMCSymbolRefExpr::Create(Kind, Symbol, Offset, Ctx)); }
static bool isSimilarDispOp(const MachineOperand &MO1, const MachineOperand &MO2) { assert(isValidDispOp(MO1) && isValidDispOp(MO2) && "Address displacement operand is not valid"); return (MO1.isImm() && MO2.isImm()) || (MO1.isCPI() && MO2.isCPI() && MO1.getIndex() == MO2.getIndex()) || (MO1.isJTI() && MO2.isJTI() && MO1.getIndex() == MO2.getIndex()) || (MO1.isSymbol() && MO2.isSymbol() && MO1.getSymbolName() == MO2.getSymbolName()) || (MO1.isGlobal() && MO2.isGlobal() && MO1.getGlobal() == MO2.getGlobal()) || (MO1.isBlockAddress() && MO2.isBlockAddress() && MO1.getBlockAddress() == MO2.getBlockAddress()) || (MO1.isMCSymbol() && MO2.isMCSymbol() && MO1.getMCSymbol() == MO2.getMCSymbol()) || (MO1.isMBB() && MO2.isMBB() && MO1.getMBB() == MO2.getMBB()); }
bool EpiphanyAsmPrinter::printSymbolicAddress(const MachineOperand &MO, bool PrintImmediatePrefix, StringRef Suffix, raw_ostream &O) { StringRef Name; StringRef Modifier; switch (MO.getType()) { default: llvm_unreachable("Unexpected operand for symbolic address constraint"); case MachineOperand::MO_GlobalAddress: Name = Mang->getSymbol(MO.getGlobal())->getName(); // Global variables may be accessed either via a GOT or in various fun and // interesting TLS-model specific ways. Set the prefix modifier as // appropriate here. if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(MO.getGlobal())) { Reloc::Model RelocM = TM.getRelocationModel(); if (Subtarget->GVIsIndirectSymbol(GV, RelocM)) { Modifier = "got"; } } break; case MachineOperand::MO_BlockAddress: Name = GetBlockAddressSymbol(MO.getBlockAddress())->getName(); break; case MachineOperand::MO_ExternalSymbol: Name = MO.getSymbolName(); break; case MachineOperand::MO_ConstantPoolIndex: Name = GetCPISymbol(MO.getIndex())->getName(); break; } // Some instructions (notably ADRP) don't take the # prefix for // immediates. Only print it if asked to. if (PrintImmediatePrefix) O << '#'; // Only need the joining "_" if both the prefix and the suffix are // non-null. This little block simply takes care of the four possibly // combinations involved there. if (Modifier == "" && Suffix == "") O << Name; else if (Modifier == "" && Suffix != "") O << ":" << Suffix << ':' << Name; else if (Modifier != "" && Suffix == "") O << ":" << Modifier << ':' << Name; else O << ":" << Modifier << '_' << Suffix << ':' << Name; return false; }
bool ARMAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) { switch (MO.getType()) { default: llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: // Ignore all non-CPSR implicit register operands. if (MO.isImplicit() && MO.getReg() != ARM::CPSR) return false; assert(!MO.getSubReg() && "Subregs should be eliminated!"); MCOp = MCOperand::createReg(MO.getReg()); break; case MachineOperand::MO_Immediate: MCOp = MCOperand::createImm(MO.getImm()); break; case MachineOperand::MO_MachineBasicBlock: MCOp = MCOperand::createExpr(MCSymbolRefExpr::create( MO.getMBB()->getSymbol(), OutContext)); break; case MachineOperand::MO_GlobalAddress: MCOp = GetSymbolRef(MO, GetARMGVSymbol(MO.getGlobal(), MO.getTargetFlags())); break; case MachineOperand::MO_ExternalSymbol: MCOp = GetSymbolRef(MO, GetExternalSymbolSymbol(MO.getSymbolName())); break; case MachineOperand::MO_JumpTableIndex: MCOp = GetSymbolRef(MO, GetJTISymbol(MO.getIndex())); break; case MachineOperand::MO_ConstantPoolIndex: if (Subtarget->genExecuteOnly()) llvm_unreachable("execute-only should not generate constant pools"); MCOp = GetSymbolRef(MO, GetCPISymbol(MO.getIndex())); break; case MachineOperand::MO_BlockAddress: MCOp = GetSymbolRef(MO, GetBlockAddressSymbol(MO.getBlockAddress())); break; case MachineOperand::MO_FPImmediate: { APFloat Val = MO.getFPImm()->getValueAPF(); bool ignored; Val.convert(APFloat::IEEEdouble(), APFloat::rmTowardZero, &ignored); MCOp = MCOperand::createFPImm(Val.convertToDouble()); break; } case MachineOperand::MO_RegisterMask: // Ignore call clobbers. return false; } return true; }
MCOperand NyuziMCInstLower::LowerSymbolOperand(const MachineOperand &MO, MachineOperandType MOTy, unsigned Offset) const { MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; const MCSymbol *Symbol; switch (MOTy) { case MachineOperand::MO_MachineBasicBlock: Symbol = MO.getMBB()->getSymbol(); break; case MachineOperand::MO_GlobalAddress: Symbol = AsmPrinter.getSymbol(MO.getGlobal()); Offset += MO.getOffset(); break; case MachineOperand::MO_BlockAddress: Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()); Offset += MO.getOffset(); break; case MachineOperand::MO_ExternalSymbol: Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName()); Offset += MO.getOffset(); break; case MachineOperand::MO_JumpTableIndex: Symbol = AsmPrinter.GetJTISymbol(MO.getIndex()); break; case MachineOperand::MO_ConstantPoolIndex: Symbol = AsmPrinter.GetCPISymbol(MO.getIndex()); Offset += MO.getOffset(); break; default: llvm_unreachable("<unknown operand type>"); } const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, Kind, *Ctx); if (!Offset) return MCOperand::createExpr(MCSym); // Assume offset is never negative. assert(Offset > 0); const MCConstantExpr *OffsetExpr = MCConstantExpr::create(Offset, *Ctx); const MCBinaryExpr *Add = MCBinaryExpr::createAdd(MCSym, OffsetExpr, *Ctx); return MCOperand::createExpr(Add); }
bool EpiphanyAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const { switch (MO.getType()) { default: llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: if (MO.isImplicit()) return false; assert(!MO.getSubReg() && "Subregs should be eliminated!"); MCOp = MCOperand::CreateReg(MO.getReg()); break; case MachineOperand::MO_Immediate: MCOp = MCOperand::CreateImm(MO.getImm()); break; case MachineOperand::MO_FPImmediate: {// a bit hacky, see arm APFloat Val = MO.getFPImm()->getValueAPF(); bool ignored; Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored); MCOp = MCOperand::CreateFPImm(Val.convertToDouble()); break; } case MachineOperand::MO_BlockAddress: MCOp = lowerSymbolOperand(MO, GetBlockAddressSymbol(MO.getBlockAddress())); break; case MachineOperand::MO_ExternalSymbol: MCOp = lowerSymbolOperand(MO, GetExternalSymbolSymbol(MO.getSymbolName())); break; case MachineOperand::MO_GlobalAddress: MCOp = lowerSymbolOperand(MO, Mang->getSymbol(MO.getGlobal())); break; case MachineOperand::MO_MachineBasicBlock: MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( MO.getMBB()->getSymbol(), OutContext)); break; case MachineOperand::MO_JumpTableIndex: MCOp = lowerSymbolOperand(MO, GetJTISymbol(MO.getIndex())); break; case MachineOperand::MO_ConstantPoolIndex: MCOp = lowerSymbolOperand(MO, GetCPISymbol(MO.getIndex())); break; case MachineOperand::MO_RegisterMask: // Ignore call clobbers return false; } return true; }
void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt, unsigned DoubleDestReg, MachineOperand &HiOperand, MachineOperand &LoOperand) { unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill()); unsigned HiReg = HiOperand.getReg(); DebugLoc DL = InsertPt->getDebugLoc(); MachineBasicBlock *BB = InsertPt->getParent(); // Handle global. if (LoOperand.isGlobal()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) .addReg(HiReg, HiRegKillFlag) .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(), LoOperand.getTargetFlags()); return; } // Handle block addresses. if (LoOperand.isBlockAddress()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) .addReg(HiReg, HiRegKillFlag) .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(), LoOperand.getTargetFlags()); return; } // Handle jump tables. if (LoOperand.isJTI()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) .addReg(HiOperand.getReg(), HiRegKillFlag) .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags()); return; } // Handle constant pools. if (LoOperand.isCPI()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) .addReg(HiOperand.getReg(), HiRegKillFlag) .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(), LoOperand.getTargetFlags()); return; } // Insert new combine instruction. // DoubleRegDest = combine HiReg, #LoImm BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) .addReg(HiReg, HiRegKillFlag) .addImm(LoOperand.getImm()); }
// Note: this must stay exactly in sync with isIdenticalTo above. hash_code llvm::hash_value(const MachineOperand &MO) { switch (MO.getType()) { case MachineOperand::MO_Register: // Register operands don't have target flags. return hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(), MO.isDef()); case MachineOperand::MO_Immediate: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm()); case MachineOperand::MO_CImmediate: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm()); case MachineOperand::MO_FPImmediate: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm()); case MachineOperand::MO_MachineBasicBlock: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB()); case MachineOperand::MO_FrameIndex: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); case MachineOperand::MO_ConstantPoolIndex: case MachineOperand::MO_TargetIndex: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(), MO.getOffset()); case MachineOperand::MO_JumpTableIndex: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); case MachineOperand::MO_ExternalSymbol: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(), MO.getSymbolName()); case MachineOperand::MO_GlobalAddress: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(), MO.getOffset()); case MachineOperand::MO_BlockAddress: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getBlockAddress(), MO.getOffset()); case MachineOperand::MO_RegisterMask: case MachineOperand::MO_RegisterLiveOut: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask()); case MachineOperand::MO_Metadata: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata()); case MachineOperand::MO_MCSymbol: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol()); case MachineOperand::MO_CFIIndex: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex()); case MachineOperand::MO_IntrinsicID: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID()); case MachineOperand::MO_Predicate: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate()); } llvm_unreachable("Invalid machine operand type"); }
bool ARMAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) { switch (MO.getType()) { default: assert(0 && "unknown operand type"); return false; case MachineOperand::MO_Register: // Ignore all non-CPSR implicit register operands. if (MO.isImplicit() && MO.getReg() != ARM::CPSR) return false; assert(!MO.getSubReg() && "Subregs should be eliminated!"); MCOp = MCOperand::CreateReg(MO.getReg()); break; case MachineOperand::MO_Immediate: MCOp = MCOperand::CreateImm(MO.getImm()); break; case MachineOperand::MO_MachineBasicBlock: MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( MO.getMBB()->getSymbol(), OutContext)); break; case MachineOperand::MO_GlobalAddress: MCOp = GetSymbolRef(MO, Mang->getSymbol(MO.getGlobal())); break; case MachineOperand::MO_ExternalSymbol: MCOp = GetSymbolRef(MO, GetExternalSymbolSymbol(MO.getSymbolName())); break; case MachineOperand::MO_JumpTableIndex: MCOp = GetSymbolRef(MO, GetJTISymbol(MO.getIndex())); break; case MachineOperand::MO_ConstantPoolIndex: MCOp = GetSymbolRef(MO, GetCPISymbol(MO.getIndex())); break; case MachineOperand::MO_BlockAddress: MCOp = GetSymbolRef(MO, GetBlockAddressSymbol(MO.getBlockAddress())); break; case MachineOperand::MO_FPImmediate: { APFloat Val = MO.getFPImm()->getValueAPF(); bool ignored; Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored); MCOp = MCOperand::CreateFPImm(Val.convertToDouble()); break; } } return true; }
MCOperand SampleMCInstLower:: LowerSymbolOperand(const MachineOperand &MO, MachineOperandType MOTy) const { DEBUG(dbgs() << ">>> LowerSymbolOperand <<<\n"); switch(MO.getTargetFlags()) { default: llvm_unreachable("Invalid target flag!"); case 0: break; } const MCSymbol *Symbol; unsigned Offset = 0; switch (MOTy) { case MachineOperand::MO_MachineBasicBlock: Symbol = MO.getMBB()->getSymbol(); break; case MachineOperand::MO_GlobalAddress: Symbol = Mang.getSymbol(MO.getGlobal()); Offset = MO.getOffset(); break; case MachineOperand::MO_BlockAddress: Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress()); break; case MachineOperand::MO_ExternalSymbol: Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName()); break; case MachineOperand::MO_JumpTableIndex: Symbol = Printer.GetJTISymbol(MO.getIndex()); break; case MachineOperand::MO_ConstantPoolIndex: Symbol = Printer.GetCPISymbol(MO.getIndex()); Offset = MO.getOffset(); break; default: llvm_unreachable("<unknown operand type>"); } const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, Ctx); if (Offset) { const MCConstantExpr *OffsetExpr = MCConstantExpr::Create(Offset, Ctx); Expr = MCBinaryExpr::CreateAdd(Expr, OffsetExpr, Ctx); } return MCOperand::CreateExpr(Expr); }
bool AArch64AsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const { switch (MO.getType()) { default: llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: if (MO.isImplicit()) return false; assert(!MO.getSubReg() && "Subregs should be eliminated!"); MCOp = MCOperand::CreateReg(MO.getReg()); break; case MachineOperand::MO_Immediate: MCOp = MCOperand::CreateImm(MO.getImm()); break; case MachineOperand::MO_FPImmediate: { assert(MO.getFPImm()->isZero() && "Only fp imm 0.0 is supported"); MCOp = MCOperand::CreateFPImm(0.0); break; } case MachineOperand::MO_BlockAddress: MCOp = lowerSymbolOperand(MO, GetBlockAddressSymbol(MO.getBlockAddress())); break; case MachineOperand::MO_ExternalSymbol: MCOp = lowerSymbolOperand(MO, GetExternalSymbolSymbol(MO.getSymbolName())); break; case MachineOperand::MO_GlobalAddress: MCOp = lowerSymbolOperand(MO, getSymbol(MO.getGlobal())); break; case MachineOperand::MO_MachineBasicBlock: MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( MO.getMBB()->getSymbol(), OutContext)); break; case MachineOperand::MO_JumpTableIndex: MCOp = lowerSymbolOperand(MO, GetJTISymbol(MO.getIndex())); break; case MachineOperand::MO_ConstantPoolIndex: MCOp = lowerSymbolOperand(MO, GetCPISymbol(MO.getIndex())); break; case MachineOperand::MO_RegisterMask: // Ignore call clobbers return false; } return true; }
bool AArch64MCInstLower::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const { switch (MO.getType()) { default: llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: // Ignore all implicit register operands. if (MO.isImplicit()) return false; MCOp = MCOperand::createReg(MO.getReg()); break; case MachineOperand::MO_RegisterMask: // Regmasks are like implicit defs. return false; case MachineOperand::MO_Immediate: MCOp = MCOperand::createImm(MO.getImm()); break; case MachineOperand::MO_MachineBasicBlock: MCOp = MCOperand::createExpr( MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); break; case MachineOperand::MO_GlobalAddress: MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO)); break; case MachineOperand::MO_ExternalSymbol: MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO)); break; case MachineOperand::MO_MCSymbol: MCOp = LowerSymbolOperand(MO, MO.getMCSymbol()); break; case MachineOperand::MO_JumpTableIndex: MCOp = LowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex())); break; case MachineOperand::MO_ConstantPoolIndex: MCOp = LowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex())); break; case MachineOperand::MO_BlockAddress: MCOp = LowerSymbolOperand( MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress())); break; } return true; }
MCOperand SystemZMCInstLower::lowerOperand(const MachineOperand &MO) const { switch (MO.getType()) { default: llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: return MCOperand::CreateReg(MO.getReg()); case MachineOperand::MO_Immediate: return MCOperand::CreateImm(MO.getImm()); case MachineOperand::MO_MachineBasicBlock: return lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), /* MO has no offset field */0); case MachineOperand::MO_GlobalAddress: return lowerSymbolOperand(MO, Mang->getSymbol(MO.getGlobal()), MO.getOffset()); case MachineOperand::MO_ExternalSymbol: { StringRef Name = MO.getSymbolName(); return lowerSymbolOperand(MO, AsmPrinter.GetExternalSymbolSymbol(Name), MO.getOffset()); } case MachineOperand::MO_JumpTableIndex: return lowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()), /* MO has no offset field */0); case MachineOperand::MO_ConstantPoolIndex: return lowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()), MO.getOffset()); case MachineOperand::MO_BlockAddress: { const BlockAddress *BA = MO.getBlockAddress(); return lowerSymbolOperand(MO, AsmPrinter.GetBlockAddressSymbol(BA), MO.getOffset()); } } }
bool llvm::LowerRISCVMachineOperandToMCOperand(const MachineOperand &MO, MCOperand &MCOp, const AsmPrinter &AP) { switch (MO.getType()) { default: report_fatal_error("LowerRISCVMachineInstrToMCInst: unknown operand type"); case MachineOperand::MO_Register: // Ignore all implicit register operands. if (MO.isImplicit()) return false; MCOp = MCOperand::createReg(MO.getReg()); break; case MachineOperand::MO_RegisterMask: // Regmasks are like implicit defs. return false; case MachineOperand::MO_Immediate: MCOp = MCOperand::createImm(MO.getImm()); break; case MachineOperand::MO_MachineBasicBlock: MCOp = lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), AP); break; case MachineOperand::MO_GlobalAddress: MCOp = lowerSymbolOperand(MO, AP.getSymbol(MO.getGlobal()), AP); break; case MachineOperand::MO_BlockAddress: MCOp = lowerSymbolOperand( MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP); break; case MachineOperand::MO_ExternalSymbol: MCOp = lowerSymbolOperand( MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP); break; case MachineOperand::MO_ConstantPoolIndex: MCOp = lowerSymbolOperand(MO, AP.GetCPISymbol(MO.getIndex()), AP); break; } return true; }
bool llvm::LowerPPCMachineOperandToMCOperand(const MachineOperand &MO, MCOperand &OutMO, AsmPrinter &AP, bool isDarwin) { switch (MO.getType()) { default: llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: assert(!MO.getSubReg() && "Subregs should be eliminated!"); assert(MO.getReg() > PPC::NoRegister && MO.getReg() < PPC::NUM_TARGET_REGS && "Invalid register for this target!"); OutMO = MCOperand::createReg(MO.getReg()); return true; case MachineOperand::MO_Immediate: OutMO = MCOperand::createImm(MO.getImm()); return true; case MachineOperand::MO_MachineBasicBlock: OutMO = MCOperand::createExpr( MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), AP.OutContext)); return true; case MachineOperand::MO_GlobalAddress: case MachineOperand::MO_ExternalSymbol: OutMO = GetSymbolRef(MO, GetSymbolFromOperand(MO, AP), AP, isDarwin); return true; case MachineOperand::MO_JumpTableIndex: OutMO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP, isDarwin); return true; case MachineOperand::MO_ConstantPoolIndex: OutMO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP, isDarwin); return true; case MachineOperand::MO_BlockAddress: OutMO = GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP, isDarwin); return true; case MachineOperand::MO_RegisterMask: return false; } }
static MCOperand LowerSymbolOperand(const MachineInstr *MI, const MachineOperand &MO, AsmPrinter &AP) { SparcMCExpr::VariantKind Kind = (SparcMCExpr::VariantKind)MO.getTargetFlags(); const MCSymbol *Symbol = nullptr; switch(MO.getType()) { default: llvm_unreachable("Unknown type in LowerSymbolOperand"); case MachineOperand::MO_MachineBasicBlock: Symbol = MO.getMBB()->getSymbol(); break; case MachineOperand::MO_GlobalAddress: Symbol = AP.getSymbol(MO.getGlobal()); break; case MachineOperand::MO_BlockAddress: Symbol = AP.GetBlockAddressSymbol(MO.getBlockAddress()); break; case MachineOperand::MO_ExternalSymbol: Symbol = AP.GetExternalSymbolSymbol(MO.getSymbolName()); break; case MachineOperand::MO_ConstantPoolIndex: Symbol = AP.GetCPISymbol(MO.getIndex()); break; } const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, AP.OutContext); const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym, AP.OutContext); return MCOperand::createExpr(expr); }
/// isIdenticalTo - Return true if this operand is identical to the specified /// operand. Note that this should stay in sync with the hash_value overload /// below. bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { if (getType() != Other.getType() || getTargetFlags() != Other.getTargetFlags()) return false; switch (getType()) { case MachineOperand::MO_Register: return getReg() == Other.getReg() && isDef() == Other.isDef() && getSubReg() == Other.getSubReg(); case MachineOperand::MO_Immediate: return getImm() == Other.getImm(); case MachineOperand::MO_CImmediate: return getCImm() == Other.getCImm(); case MachineOperand::MO_FPImmediate: return getFPImm() == Other.getFPImm(); case MachineOperand::MO_MachineBasicBlock: return getMBB() == Other.getMBB(); case MachineOperand::MO_FrameIndex: return getIndex() == Other.getIndex(); case MachineOperand::MO_ConstantPoolIndex: case MachineOperand::MO_TargetIndex: return getIndex() == Other.getIndex() && getOffset() == Other.getOffset(); case MachineOperand::MO_JumpTableIndex: return getIndex() == Other.getIndex(); case MachineOperand::MO_GlobalAddress: return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); case MachineOperand::MO_ExternalSymbol: return strcmp(getSymbolName(), Other.getSymbolName()) == 0 && getOffset() == Other.getOffset(); case MachineOperand::MO_BlockAddress: return getBlockAddress() == Other.getBlockAddress() && getOffset() == Other.getOffset(); case MachineOperand::MO_RegisterMask: case MachineOperand::MO_RegisterLiveOut: { // Shallow compare of the two RegMasks const uint32_t *RegMask = getRegMask(); const uint32_t *OtherRegMask = Other.getRegMask(); if (RegMask == OtherRegMask) return true; if (const MachineFunction *MF = getMFIfAvailable(*this)) { // Calculate the size of the RegMask const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); unsigned RegMaskSize = (TRI->getNumRegs() + 31) / 32; // Deep compare of the two RegMasks return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask); } // We don't know the size of the RegMask, so we can't deep compare the two // reg masks. return false; } case MachineOperand::MO_MCSymbol: return getMCSymbol() == Other.getMCSymbol(); case MachineOperand::MO_CFIIndex: return getCFIIndex() == Other.getCFIIndex(); case MachineOperand::MO_Metadata: return getMetadata() == Other.getMetadata(); case MachineOperand::MO_IntrinsicID: return getIntrinsicID() == Other.getIntrinsicID(); case MachineOperand::MO_Predicate: return getPredicate() == Other.getPredicate(); } llvm_unreachable("Invalid machine operand type"); }
void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt, unsigned DoubleDestReg, MachineOperand &HiOperand, MachineOperand &LoOperand) { DebugLoc DL = InsertPt->getDebugLoc(); MachineBasicBlock *BB = InsertPt->getParent(); // Handle globals. if (HiOperand.isGlobal()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), HiOperand.getTargetFlags()) .addImm(LoOperand.getImm()); return; } if (LoOperand.isGlobal()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) .addImm(HiOperand.getImm()) .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(), LoOperand.getTargetFlags()); return; } // Handle block addresses. if (HiOperand.isBlockAddress()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(), HiOperand.getTargetFlags()) .addImm(LoOperand.getImm()); return; } if (LoOperand.isBlockAddress()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) .addImm(HiOperand.getImm()) .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(), LoOperand.getTargetFlags()); return; } // Handle jump tables. if (HiOperand.isJTI()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags()) .addImm(LoOperand.getImm()); return; } if (LoOperand.isJTI()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) .addImm(HiOperand.getImm()) .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags()); return; } // Handle constant pools. if (HiOperand.isCPI()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(), HiOperand.getTargetFlags()) .addImm(LoOperand.getImm()); return; } if (LoOperand.isCPI()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) .addImm(HiOperand.getImm()) .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(), LoOperand.getTargetFlags()); return; } // First preference should be given to Hexagon::A2_combineii instruction // as it can include U6 (in Hexagon::A4_combineii) as well. // In this instruction, HiOperand is const extended, if required. if (isInt<8>(LoOperand.getImm())) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) .addImm(HiOperand.getImm()) .addImm(LoOperand.getImm()); return; } // In this instruction, LoOperand is const extended, if required. if (isInt<8>(HiOperand.getImm())) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) .addImm(HiOperand.getImm()) .addImm(LoOperand.getImm()); return; } // Insert new combine instruction. // DoubleRegDest = combine #HiImm, #LoImm BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) .addImm(HiOperand.getImm()) .addImm(LoOperand.getImm()); }
MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO, MachineOperandType MOTy, unsigned Offset) const { MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; MipsMCExpr::MipsExprKind TargetKind = MipsMCExpr::MEK_None; bool IsGpOff = false; const MCSymbol *Symbol; switch(MO.getTargetFlags()) { default: llvm_unreachable("Invalid target flag!"); case MipsII::MO_NO_FLAG: break; case MipsII::MO_GPREL: TargetKind = MipsMCExpr::MEK_GPREL; break; case MipsII::MO_GOT_CALL: TargetKind = MipsMCExpr::MEK_GOT_CALL; break; case MipsII::MO_GOT: TargetKind = MipsMCExpr::MEK_GOT; break; case MipsII::MO_ABS_HI: TargetKind = MipsMCExpr::MEK_HI; break; case MipsII::MO_ABS_LO: TargetKind = MipsMCExpr::MEK_LO; break; case MipsII::MO_TLSGD: TargetKind = MipsMCExpr::MEK_TLSGD; break; case MipsII::MO_TLSLDM: TargetKind = MipsMCExpr::MEK_TLSLDM; break; case MipsII::MO_DTPREL_HI: TargetKind = MipsMCExpr::MEK_DTPREL_HI; break; case MipsII::MO_DTPREL_LO: TargetKind = MipsMCExpr::MEK_DTPREL_LO; break; case MipsII::MO_GOTTPREL: TargetKind = MipsMCExpr::MEK_GOTTPREL; break; case MipsII::MO_TPREL_HI: TargetKind = MipsMCExpr::MEK_TPREL_HI; break; case MipsII::MO_TPREL_LO: TargetKind = MipsMCExpr::MEK_TPREL_LO; break; case MipsII::MO_GPOFF_HI: TargetKind = MipsMCExpr::MEK_HI; IsGpOff = true; break; case MipsII::MO_GPOFF_LO: TargetKind = MipsMCExpr::MEK_LO; IsGpOff = true; break; case MipsII::MO_GOT_DISP: TargetKind = MipsMCExpr::MEK_GOT_DISP; break; case MipsII::MO_GOT_HI16: TargetKind = MipsMCExpr::MEK_GOT_HI16; break; case MipsII::MO_GOT_LO16: TargetKind = MipsMCExpr::MEK_GOT_LO16; break; case MipsII::MO_GOT_PAGE: TargetKind = MipsMCExpr::MEK_GOT_PAGE; break; case MipsII::MO_GOT_OFST: TargetKind = MipsMCExpr::MEK_GOT_OFST; break; case MipsII::MO_HIGHER: TargetKind = MipsMCExpr::MEK_HIGHER; break; case MipsII::MO_HIGHEST: TargetKind = MipsMCExpr::MEK_HIGHEST; break; case MipsII::MO_CALL_HI16: TargetKind = MipsMCExpr::MEK_CALL_HI16; break; case MipsII::MO_CALL_LO16: TargetKind = MipsMCExpr::MEK_CALL_LO16; break; } switch (MOTy) { case MachineOperand::MO_MachineBasicBlock: Symbol = MO.getMBB()->getSymbol(); break; case MachineOperand::MO_GlobalAddress: Symbol = AsmPrinter.getSymbol(MO.getGlobal()); Offset += MO.getOffset(); break; case MachineOperand::MO_BlockAddress: Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()); Offset += MO.getOffset(); break; case MachineOperand::MO_ExternalSymbol: Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName()); Offset += MO.getOffset(); break; case MachineOperand::MO_MCSymbol: Symbol = MO.getMCSymbol(); Offset += MO.getOffset(); break; case MachineOperand::MO_JumpTableIndex: Symbol = AsmPrinter.GetJTISymbol(MO.getIndex()); break; case MachineOperand::MO_ConstantPoolIndex: Symbol = AsmPrinter.GetCPISymbol(MO.getIndex()); Offset += MO.getOffset(); break; default: llvm_unreachable("<unknown operand type>"); } const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, *Ctx); if (Offset) { // Assume offset is never negative. assert(Offset > 0); Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, *Ctx), *Ctx); } if (IsGpOff) Expr = MipsMCExpr::createGpOff(TargetKind, Expr, *Ctx); else if (TargetKind != MipsMCExpr::MEK_None) Expr = MipsMCExpr::create(TargetKind, Expr, *Ctx); return MCOperand::createExpr(Expr); }
void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { printTargetFlags(Op); switch (Op.getType()) { case MachineOperand::MO_Register: // TODO: Print the other register flags. if (Op.isImplicit()) OS << (Op.isDef() ? "implicit-def " : "implicit "); if (Op.isDead()) OS << "dead "; if (Op.isKill()) OS << "killed "; if (Op.isUndef()) OS << "undef "; if (Op.isEarlyClobber()) OS << "early-clobber "; if (Op.isDebug()) OS << "debug-use "; printReg(Op.getReg(), OS, TRI); // Print the sub register. if (Op.getSubReg() != 0) OS << ':' << TRI->getSubRegIndexName(Op.getSubReg()); break; case MachineOperand::MO_Immediate: OS << Op.getImm(); break; case MachineOperand::MO_CImmediate: Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); break; case MachineOperand::MO_FPImmediate: Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); break; case MachineOperand::MO_MachineBasicBlock: printMBBReference(*Op.getMBB()); break; case MachineOperand::MO_FrameIndex: printStackObjectReference(Op.getIndex()); break; case MachineOperand::MO_ConstantPoolIndex: OS << "%const." << Op.getIndex(); printOffset(Op.getOffset()); break; case MachineOperand::MO_TargetIndex: { OS << "target-index("; if (const auto *Name = getTargetIndexName( *Op.getParent()->getParent()->getParent(), Op.getIndex())) OS << Name; else OS << "<unknown>"; OS << ')'; printOffset(Op.getOffset()); break; } case MachineOperand::MO_JumpTableIndex: OS << "%jump-table." << Op.getIndex(); break; case MachineOperand::MO_ExternalSymbol: OS << '$'; printLLVMNameWithoutPrefix(OS, Op.getSymbolName()); printOffset(Op.getOffset()); break; case MachineOperand::MO_GlobalAddress: Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); printOffset(Op.getOffset()); break; case MachineOperand::MO_BlockAddress: OS << "blockaddress("; Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, MST); OS << ", "; printIRBlockReference(*Op.getBlockAddress()->getBasicBlock()); OS << ')'; printOffset(Op.getOffset()); break; case MachineOperand::MO_RegisterMask: { auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); if (RegMaskInfo != RegisterMaskIds.end()) OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); else llvm_unreachable("Can't print this machine register mask yet."); break; } case MachineOperand::MO_Metadata: Op.getMetadata()->printAsOperand(OS, MST); break; case MachineOperand::MO_CFIIndex: { const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI(); print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI); break; } default: // TODO: Print the other machine operands. llvm_unreachable("Can't print this machine operand at the moment"); } }
void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI, unsigned I, bool ShouldPrintRegisterTies, bool IsDef) { printTargetFlags(Op); switch (Op.getType()) { case MachineOperand::MO_Register: if (Op.isImplicit()) OS << (Op.isDef() ? "implicit-def " : "implicit "); else if (!IsDef && Op.isDef()) // Print the 'def' flag only when the operand is defined after '='. OS << "def "; if (Op.isInternalRead()) OS << "internal "; if (Op.isDead()) OS << "dead "; if (Op.isKill()) OS << "killed "; if (Op.isUndef()) OS << "undef "; if (Op.isEarlyClobber()) OS << "early-clobber "; if (Op.isDebug()) OS << "debug-use "; printReg(Op.getReg(), OS, TRI); // Print the sub register. if (Op.getSubReg() != 0) OS << ':' << TRI->getSubRegIndexName(Op.getSubReg()); if (ShouldPrintRegisterTies && Op.isTied() && !Op.isDef()) OS << "(tied-def " << Op.getParent()->findTiedOperandIdx(I) << ")"; break; case MachineOperand::MO_Immediate: OS << Op.getImm(); break; case MachineOperand::MO_CImmediate: Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); break; case MachineOperand::MO_FPImmediate: Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); break; case MachineOperand::MO_MachineBasicBlock: printMBBReference(*Op.getMBB()); break; case MachineOperand::MO_FrameIndex: printStackObjectReference(Op.getIndex()); break; case MachineOperand::MO_ConstantPoolIndex: OS << "%const." << Op.getIndex(); printOffset(Op.getOffset()); break; case MachineOperand::MO_TargetIndex: { OS << "target-index("; if (const auto *Name = getTargetIndexName( *Op.getParent()->getParent()->getParent(), Op.getIndex())) OS << Name; else OS << "<unknown>"; OS << ')'; printOffset(Op.getOffset()); break; } case MachineOperand::MO_JumpTableIndex: OS << "%jump-table." << Op.getIndex(); break; case MachineOperand::MO_ExternalSymbol: OS << '$'; printLLVMNameWithoutPrefix(OS, Op.getSymbolName()); printOffset(Op.getOffset()); break; case MachineOperand::MO_GlobalAddress: Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); printOffset(Op.getOffset()); break; case MachineOperand::MO_BlockAddress: OS << "blockaddress("; Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, MST); OS << ", "; printIRBlockReference(*Op.getBlockAddress()->getBasicBlock()); OS << ')'; printOffset(Op.getOffset()); break; case MachineOperand::MO_RegisterMask: { auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); if (RegMaskInfo != RegisterMaskIds.end()) OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); else llvm_unreachable("Can't print this machine register mask yet."); break; } case MachineOperand::MO_RegisterLiveOut: { const uint32_t *RegMask = Op.getRegLiveOut(); OS << "liveout("; bool IsCommaNeeded = false; for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { if (RegMask[Reg / 32] & (1U << (Reg % 32))) { if (IsCommaNeeded) OS << ", "; printReg(Reg, OS, TRI); IsCommaNeeded = true; } } OS << ")"; break; } case MachineOperand::MO_Metadata: Op.getMetadata()->printAsOperand(OS, MST); break; case MachineOperand::MO_MCSymbol: OS << "<mcsymbol " << *Op.getMCSymbol() << ">"; break; case MachineOperand::MO_CFIIndex: { const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI(); print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI); break; } } }
MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO, MachineOperandType MOTy, unsigned Offset) const { MCSymbolRefExpr::VariantKind Kind; const MCSymbol *Symbol; switch(MO.getTargetFlags()) { default: llvm_unreachable("Invalid target flag!"); case MipsII::MO_NO_FLAG: Kind = MCSymbolRefExpr::VK_None; break; case MipsII::MO_GPREL: Kind = MCSymbolRefExpr::VK_Mips_GPREL; break; case MipsII::MO_GOT_CALL: Kind = MCSymbolRefExpr::VK_Mips_GOT_CALL; break; case MipsII::MO_GOT16: Kind = MCSymbolRefExpr::VK_Mips_GOT16; break; case MipsII::MO_GOT: Kind = MCSymbolRefExpr::VK_Mips_GOT; break; case MipsII::MO_ABS_HI: Kind = MCSymbolRefExpr::VK_Mips_ABS_HI; break; case MipsII::MO_ABS_LO: Kind = MCSymbolRefExpr::VK_Mips_ABS_LO; break; case MipsII::MO_TLSGD: Kind = MCSymbolRefExpr::VK_Mips_TLSGD; break; case MipsII::MO_TLSLDM: Kind = MCSymbolRefExpr::VK_Mips_TLSLDM; break; case MipsII::MO_DTPREL_HI: Kind = MCSymbolRefExpr::VK_Mips_DTPREL_HI; break; case MipsII::MO_DTPREL_LO: Kind = MCSymbolRefExpr::VK_Mips_DTPREL_LO; break; case MipsII::MO_GOTTPREL: Kind = MCSymbolRefExpr::VK_Mips_GOTTPREL; break; case MipsII::MO_TPREL_HI: Kind = MCSymbolRefExpr::VK_Mips_TPREL_HI; break; case MipsII::MO_TPREL_LO: Kind = MCSymbolRefExpr::VK_Mips_TPREL_LO; break; case MipsII::MO_GPOFF_HI: Kind = MCSymbolRefExpr::VK_Mips_GPOFF_HI; break; case MipsII::MO_GPOFF_LO: Kind = MCSymbolRefExpr::VK_Mips_GPOFF_LO; break; case MipsII::MO_GOT_DISP: Kind = MCSymbolRefExpr::VK_Mips_GOT_DISP; break; case MipsII::MO_GOT_PAGE: Kind = MCSymbolRefExpr::VK_Mips_GOT_PAGE; break; case MipsII::MO_GOT_OFST: Kind = MCSymbolRefExpr::VK_Mips_GOT_OFST; break; case MipsII::MO_HIGHER: Kind = MCSymbolRefExpr::VK_Mips_HIGHER; break; case MipsII::MO_HIGHEST: Kind = MCSymbolRefExpr::VK_Mips_HIGHEST; break; case MipsII::MO_GOT_HI16: Kind = MCSymbolRefExpr::VK_Mips_GOT_HI16; break; case MipsII::MO_GOT_LO16: Kind = MCSymbolRefExpr::VK_Mips_GOT_LO16; break; case MipsII::MO_CALL_HI16: Kind = MCSymbolRefExpr::VK_Mips_CALL_HI16; break; case MipsII::MO_CALL_LO16: Kind = MCSymbolRefExpr::VK_Mips_CALL_LO16; break; } switch (MOTy) { case MachineOperand::MO_MachineBasicBlock: Symbol = MO.getMBB()->getSymbol(); break; case MachineOperand::MO_GlobalAddress: Symbol = AsmPrinter.getSymbol(MO.getGlobal()); Offset += MO.getOffset(); break; case MachineOperand::MO_BlockAddress: Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()); Offset += MO.getOffset(); break; case MachineOperand::MO_ExternalSymbol: Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName()); Offset += MO.getOffset(); break; case MachineOperand::MO_JumpTableIndex: Symbol = AsmPrinter.GetJTISymbol(MO.getIndex()); break; case MachineOperand::MO_ConstantPoolIndex: Symbol = AsmPrinter.GetCPISymbol(MO.getIndex()); Offset += MO.getOffset(); break; default: llvm_unreachable("<unknown operand type>"); } const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, Kind, *Ctx); if (!Offset) return MCOperand::CreateExpr(MCSym); // Assume offset is never negative. assert(Offset > 0); const MCConstantExpr *OffsetExpr = MCConstantExpr::Create(Offset, *Ctx); const MCBinaryExpr *Add = MCBinaryExpr::CreateAdd(MCSym, OffsetExpr, *Ctx); return MCOperand::CreateExpr(Add); }
void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI, unsigned I, bool ShouldPrintRegisterTies, LLT TypeToPrint, bool IsDef) { printTargetFlags(Op); switch (Op.getType()) { case MachineOperand::MO_Register: if (Op.isImplicit()) OS << (Op.isDef() ? "implicit-def " : "implicit "); else if (!IsDef && Op.isDef()) // Print the 'def' flag only when the operand is defined after '='. OS << "def "; if (Op.isInternalRead()) OS << "internal "; if (Op.isDead()) OS << "dead "; if (Op.isKill()) OS << "killed "; if (Op.isUndef()) OS << "undef "; if (Op.isEarlyClobber()) OS << "early-clobber "; if (Op.isDebug()) OS << "debug-use "; printReg(Op.getReg(), OS, TRI); // Print the sub register. if (Op.getSubReg() != 0) OS << '.' << TRI->getSubRegIndexName(Op.getSubReg()); if (ShouldPrintRegisterTies && Op.isTied() && !Op.isDef()) OS << "(tied-def " << Op.getParent()->findTiedOperandIdx(I) << ")"; if (TypeToPrint.isValid()) OS << '(' << TypeToPrint << ')'; break; case MachineOperand::MO_Immediate: OS << Op.getImm(); break; case MachineOperand::MO_CImmediate: Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); break; case MachineOperand::MO_FPImmediate: Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); break; case MachineOperand::MO_MachineBasicBlock: printMBBReference(*Op.getMBB()); break; case MachineOperand::MO_FrameIndex: printStackObjectReference(Op.getIndex()); break; case MachineOperand::MO_ConstantPoolIndex: OS << "%const." << Op.getIndex(); printOffset(Op.getOffset()); break; case MachineOperand::MO_TargetIndex: OS << "target-index("; if (const auto *Name = getTargetIndexName( *Op.getParent()->getParent()->getParent(), Op.getIndex())) OS << Name; else OS << "<unknown>"; OS << ')'; printOffset(Op.getOffset()); break; case MachineOperand::MO_JumpTableIndex: OS << "%jump-table." << Op.getIndex(); break; case MachineOperand::MO_ExternalSymbol: { StringRef Name = Op.getSymbolName(); OS << '$'; if (Name.empty()) { OS << "\"\""; } else { printLLVMNameWithoutPrefix(OS, Name); } printOffset(Op.getOffset()); break; } case MachineOperand::MO_GlobalAddress: Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); printOffset(Op.getOffset()); break; case MachineOperand::MO_BlockAddress: OS << "blockaddress("; Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, MST); OS << ", "; printIRBlockReference(*Op.getBlockAddress()->getBasicBlock()); OS << ')'; printOffset(Op.getOffset()); break; case MachineOperand::MO_RegisterMask: { auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); if (RegMaskInfo != RegisterMaskIds.end()) OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); else printCustomRegMask(Op.getRegMask(), OS, TRI); break; } case MachineOperand::MO_RegisterLiveOut: { const uint32_t *RegMask = Op.getRegLiveOut(); OS << "liveout("; bool IsCommaNeeded = false; for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { if (RegMask[Reg / 32] & (1U << (Reg % 32))) { if (IsCommaNeeded) OS << ", "; printReg(Reg, OS, TRI); IsCommaNeeded = true; } } OS << ")"; break; } case MachineOperand::MO_Metadata: Op.getMetadata()->printAsOperand(OS, MST); break; case MachineOperand::MO_MCSymbol: OS << "<mcsymbol " << *Op.getMCSymbol() << ">"; break; case MachineOperand::MO_CFIIndex: { const MachineFunction &MF = *Op.getParent()->getParent()->getParent(); print(MF.getFrameInstructions()[Op.getCFIIndex()], TRI); break; } case MachineOperand::MO_IntrinsicID: { Intrinsic::ID ID = Op.getIntrinsicID(); if (ID < Intrinsic::num_intrinsics) OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')'; else { const MachineFunction &MF = *Op.getParent()->getParent()->getParent(); const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo(); OS << "intrinsic(@" << TII->getName(ID) << ')'; } break; } case MachineOperand::MO_Predicate: { auto Pred = static_cast<CmpInst::Predicate>(Op.getPredicate()); OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred(" << CmpInst::getPredicateName(Pred) << ')'; break; } } }