/// getMachineOpValue - Return binary encoding of operand. If the machine /// operand requires relocation, record the relocation and return zero. unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI, const MachineOperand &MO) const { if (MO.isReg()) return MipsRegisterInfo::getRegisterNumbering(MO.getReg()); else if (MO.isImm()) return static_cast<unsigned>(MO.getImm()); else if (MO.isGlobal()) { if (MI.getOpcode() == Mips::ULW || MI.getOpcode() == Mips::USW || MI.getOpcode() == Mips::ULH || MI.getOpcode() == Mips::ULHu) emitGlobalAddressUnaligned(MO.getGlobal(), getRelocation(MI, MO), 4); else if (MI.getOpcode() == Mips::USH) emitGlobalAddressUnaligned(MO.getGlobal(), getRelocation(MI, MO), 8); else emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true); } else if (MO.isSymbol()) emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO)); else if (MO.isCPI()) emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO)); else if (MO.isJTI()) emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO)); else if (MO.isMBB()) emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO)); else llvm_unreachable("Unable to encode MachineOperand!"); return 0; }
MachineRelocation PPCCodeEmitter::GetRelocation(const MachineOperand &MO, unsigned RelocID) const { // If in PIC mode, we need to encode the negated address of the // 'movepctolr' into the unrelocated field. After relocation, we'll have // &gv-&movepctolr-4 in the imm field. Once &movepctolr is added to the imm // field, we get &gv. This doesn't happen for branch relocations, which are // always implicitly pc relative. intptr_t Cst = 0; if (TM.getRelocationModel() == Reloc::PIC_) { assert(MovePCtoLROffset && "MovePCtoLR not seen yet?"); Cst = -(intptr_t)MovePCtoLROffset - 4; } if (MO.isGlobal()) return MachineRelocation::getGV(MCE.getCurrentPCOffset(), RelocID, const_cast<GlobalValue *>(MO.getGlobal()), Cst, isa<Function>(MO.getGlobal())); if (MO.isSymbol()) return MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), RelocID, MO.getSymbolName(), Cst); if (MO.isCPI()) return MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), RelocID, MO.getIndex(), Cst); if (MO.isMBB()) return MachineRelocation::getBB(MCE.getCurrentPCOffset(), RelocID, MO.getMBB()); assert(MO.isJTI()); return MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), RelocID, MO.getIndex(), Cst); }
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; }
/// getMachineOpValue - Return binary encoding of operand. If the machine /// operand requires relocation, record the relocation and return zero. unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI, const MachineOperand &MO) { if (MO.isReg()) return ARMRegisterInfo::getRegisterNumbering(MO.getReg()); else if (MO.isImm()) return static_cast<unsigned>(MO.getImm()); else if (MO.isGlobal()) emitGlobalAddress(MO.getGlobal(), ARM::reloc_arm_branch, true, false); else if (MO.isSymbol()) emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_branch); else if (MO.isCPI()) { const TargetInstrDesc &TID = MI.getDesc(); // For VFP load, the immediate offset is multiplied by 4. unsigned Reloc = ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPLdStFrm) ? ARM::reloc_arm_vfp_cp_entry : ARM::reloc_arm_cp_entry; emitConstPoolAddress(MO.getIndex(), Reloc); } else if (MO.isJTI()) emitJumpTableAddress(MO.getIndex(), ARM::reloc_arm_relative); else if (MO.isMBB()) emitMachineBasicBlock(MO.getMBB(), ARM::reloc_arm_branch); else { #ifndef NDEBUG errs() << MO; #endif llvm_unreachable(0); } return 0; }
void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { switch (Op.getType()) { case MachineOperand::MO_Register: // TODO: Print register flags. printReg(Op.getReg(), OS, TRI); // TODO: Print sub register. break; case MachineOperand::MO_Immediate: OS << Op.getImm(); break; case MachineOperand::MO_MachineBasicBlock: OS << "%bb." << Op.getMBB()->getNumber(); if (const auto *BB = Op.getMBB()->getBasicBlock()) { if (BB->hasName()) OS << '.' << BB->getName(); } break; case MachineOperand::MO_GlobalAddress: // FIXME: Make this faster - print as operand will create a slot tracker to // print unnamed values for the whole module every time it's called, which // is inefficient. Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, &M); // TODO: Print offset and target flags. break; default: // TODO: Print the other machine operands. llvm_unreachable("Can't print this machine operand at the moment"); } }
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); }
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; } // Insert new combine instruction. // DoubleRegDest = combine HiReg, #LoImm BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) .addReg(HiReg, HiRegKillFlag) .addImm(LoOperand.getImm()); }
/// isIdenticalTo - Return true if this operand is identical to the specified /// operand. bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { if (getType() != Other.getType()) return false; switch (getType()) { default: assert(0 && "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(); } }
unsigned MipsCodeEmitter::getOperandValue(const MachineOperand &MO, unsigned relocType) { switch (MO.getType()) { case MachineOperand::MO_Immediate: return MO.getImm(); case MachineOperand::MO_GlobalAddress: emitGlobalAddress(MO.getGlobal(), relocType, false); return 0; case MachineOperand::MO_ExternalSymbol: emitExternalSymbolAddress(MO.getSymbolName(), relocType); return 0; case MachineOperand::MO_MachineBasicBlock: emitMachineBasicBlock(MO.getMBB(), relocType, MCE.getCurrentPCValue()); return 0; case MachineOperand::MO_Register: return MipsRegisterInfo::getRegisterNumbering(MO.getReg()); case MachineOperand::MO_JumpTableIndex: emitJumpTableAddress(MO.getIndex(), relocType); return 0; case MachineOperand::MO_ConstantPoolIndex: emitConstPoolAddress(MO.getIndex(), relocType); return 0; default: return 0; } }
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)); }
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 constant extended immediates. if (!isInt<8>(HiOperand.getImm())) { assert(isInt<8>(LoOperand.getImm())); BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) .addImm(HiOperand.getImm()) .addImm(LoOperand.getImm()); return; } if (!isUInt<6>(LoOperand.getImm())) { assert(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()); }
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 HexagonOptAddrMode::changeLoad(MachineInstr *OldMI, MachineOperand ImmOp, unsigned ImmOpNum) { bool Changed = false; MachineBasicBlock *BB = OldMI->getParent(); auto UsePos = MachineBasicBlock::iterator(OldMI); MachineBasicBlock::instr_iterator InsertPt = UsePos.getInstrIterator(); ++InsertPt; unsigned OpStart; unsigned OpEnd = OldMI->getNumOperands(); MachineInstrBuilder MIB; if (ImmOpNum == 1) { if (HII->getAddrMode(OldMI) == HexagonII::BaseRegOffset) { short NewOpCode = HII->getBaseWithLongOffset(OldMI); assert(NewOpCode >= 0 && "Invalid New opcode\n"); MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode)); MIB.addOperand(OldMI->getOperand(0)); MIB.addOperand(OldMI->getOperand(2)); MIB.addOperand(OldMI->getOperand(3)); MIB.addOperand(ImmOp); OpStart = 4; Changed = true; } else if (HII->getAddrMode(OldMI) == HexagonII::BaseImmOffset) { short NewOpCode = HII->getAbsoluteForm(OldMI); assert(NewOpCode >= 0 && "Invalid New opcode\n"); MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode)) .addOperand(OldMI->getOperand(0)); const GlobalValue *GV = ImmOp.getGlobal(); int64_t Offset = ImmOp.getOffset() + OldMI->getOperand(2).getImm(); MIB.addGlobalAddress(GV, Offset, ImmOp.getTargetFlags()); OpStart = 3; Changed = true; } else Changed = false; DEBUG(dbgs() << "[Changing]: " << *OldMI << "\n"); DEBUG(dbgs() << "[TO]: " << MIB << "\n"); } else if (ImmOpNum == 2 && OldMI->getOperand(3).getImm() == 0) { short NewOpCode = HII->xformRegToImmOffset(OldMI); assert(NewOpCode >= 0 && "Invalid New opcode\n"); MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode)); MIB.addOperand(OldMI->getOperand(0)); MIB.addOperand(OldMI->getOperand(1)); MIB.addOperand(ImmOp); OpStart = 4; Changed = true; DEBUG(dbgs() << "[Changing]: " << *OldMI << "\n"); DEBUG(dbgs() << "[TO]: " << MIB << "\n"); } if (Changed) for (unsigned i = OpStart; i < OpEnd; ++i) MIB.addOperand(OldMI->getOperand(i)); return Changed; }
unsigned MipsCodeEmitter::getJumpTargetOpValue(const MachineInstr &MI, unsigned OpNo) const { MachineOperand MO = MI.getOperand(OpNo); if (MO.isGlobal()) emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true); else if (MO.isSymbol()) emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO)); else if (MO.isMBB()) emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO)); else llvm_unreachable("Unexpected jump target operand kind."); return 0; }
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 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; }
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::emitCombineIR(MachineBasicBlock::iterator &InsertPt, unsigned DoubleDestReg, MachineOperand &HiOperand, MachineOperand &LoOperand) { unsigned LoReg = LoOperand.getReg(); unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill()); DebugLoc DL = InsertPt->getDebugLoc(); MachineBasicBlock *BB = InsertPt->getParent(); // Handle globals. if (HiOperand.isGlobal()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), HiOperand.getTargetFlags()) .addReg(LoReg, LoRegKillFlag); return; } // Handle block addresses. if (HiOperand.isBlockAddress()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(), HiOperand.getTargetFlags()) .addReg(LoReg, LoRegKillFlag); return; } // Handle jump tables. if (HiOperand.isJTI()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags()) .addReg(LoReg, LoRegKillFlag); return; } // Handle constant pools. if (HiOperand.isCPI()) { BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(), HiOperand.getTargetFlags()) .addReg(LoReg, LoRegKillFlag); return; } // Insert new combine instruction. // DoubleRegDest = combine #HiImm, LoReg BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) .addImm(HiOperand.getImm()) .addReg(LoReg, LoRegKillFlag); }
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 AMDGPUMCInstLower::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const { switch (MO.getType()) { default: llvm_unreachable("unknown operand type"); case MachineOperand::MO_Immediate: MCOp = MCOperand::createImm(MO.getImm()); return true; case MachineOperand::MO_Register: MCOp = MCOperand::createReg(AMDGPU::getMCReg(MO.getReg(), ST)); return true; case MachineOperand::MO_MachineBasicBlock: { if (MO.getTargetFlags() != 0) { MCOp = MCOperand::createExpr( getLongBranchBlockExpr(*MO.getParent()->getParent(), MO)); } else { MCOp = MCOperand::createExpr( MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); } return true; } case MachineOperand::MO_GlobalAddress: { const GlobalValue *GV = MO.getGlobal(); SmallString<128> SymbolName; AP.getNameWithPrefix(SymbolName, GV); MCSymbol *Sym = Ctx.getOrCreateSymbol(SymbolName); const MCExpr *SymExpr = MCSymbolRefExpr::create(Sym, getVariantKind(MO.getTargetFlags()),Ctx); const MCExpr *Expr = MCBinaryExpr::createAdd(SymExpr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); MCOp = MCOperand::createExpr(Expr); return true; } case MachineOperand::MO_ExternalSymbol: { MCSymbol *Sym = Ctx.getOrCreateSymbol(StringRef(MO.getSymbolName())); Sym->setExternal(true); const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx); MCOp = MCOperand::createExpr(Expr); return true; } case MachineOperand::MO_RegisterMask: // Regmasks are like implicit defs. return false; } }
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; }
// 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 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; }
void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { const TargetRegisterInfo &RI = *TM.getRegisterInfo(); switch (MO.getType()) { case MachineOperand::MO_Register: O << RI.get(MO.getReg()).AsmName; return; case MachineOperand::MO_Immediate: cerr << "printOp() does not handle immediate values\n"; abort(); return; case MachineOperand::MO_MachineBasicBlock: printBasicBlockLabel(MO.getMBB()); return; case MachineOperand::MO_ConstantPoolIndex: O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" << MO.getIndex(); return; case MachineOperand::MO_ExternalSymbol: O << MO.getSymbolName(); return; case MachineOperand::MO_GlobalAddress: { GlobalValue *GV = MO.getGlobal(); O << Mang->getValueName(GV); if (GV->isDeclaration() && GV->hasExternalWeakLinkage()) ExtWeakSymbols.insert(GV); return; } case MachineOperand::MO_JumpTableIndex: O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << MO.getIndex(); return; default: O << "<unknown operand type: " << MO.getType() << ">"; return; } }
/// getMachineOpValue - Return binary encoding of operand. If the machine /// operand requires relocation, record the relocation and return zero. unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI, const MachineOperand &MO) const { if (MO.isReg()) return TM.getRegisterInfo()->getEncodingValue(MO.getReg()); else if (MO.isImm()) return static_cast<unsigned>(MO.getImm()); else if (MO.isGlobal()) emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true); else if (MO.isSymbol()) emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO)); else if (MO.isCPI()) emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO)); else if (MO.isJTI()) emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO)); else if (MO.isMBB()) emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO)); else llvm_unreachable("Unable to encode MachineOperand!"); return 0; }
MCOperand PTXAsmPrinter::lowerOperand(const MachineOperand &MO) { MCOperand MCOp; const PTXMachineFunctionInfo *MFI = MF->getInfo<PTXMachineFunctionInfo>(); const MCExpr *Expr; const char *RegSymbolName; switch (MO.getType()) { default: llvm_unreachable("Unknown operand type"); case MachineOperand::MO_Register: // We create register operands as symbols, since the PTXInstPrinter class // has no way to map virtual registers back to a name without some ugly // hacks. // FIXME: Figure out a better way to handle virtual register naming. RegSymbolName = MFI->getRegisterName(MO.getReg()); Expr = MCSymbolRefExpr::Create(RegSymbolName, MCSymbolRefExpr::VK_None, OutContext); MCOp = MCOperand::CreateExpr(Expr); 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_FPImmediate: APFloat Val = MO.getFPImm()->getValueAPF(); bool ignored; Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored); MCOp = MCOperand::CreateFPImm(Val.convertToDouble()); break; } return MCOp; }
MCOperand rvexMCInstLower::LowerSymbolOperand(const MachineOperand &MO, MachineOperandType MOTy, unsigned Offset) const { MCSymbolRefExpr::VariantKind Kind; const MCSymbol *Symbol; switch(MO.getTargetFlags()) { default: llvm_unreachable("Invalid target flag!"); // rvex_GPREL is for llc -march=rvex -relocation-model=static -rvex-islinux- // format=false (global var in .sdata). case rvexII::MO_GPREL: Kind = MCSymbolRefExpr::VK_Cpu0_GPREL; break; case rvexII::MO_GOT16: Kind = MCSymbolRefExpr::VK_Cpu0_GOT16; break; case rvexII::MO_GOT: Kind = MCSymbolRefExpr::VK_Cpu0_GOT; break; // ABS_HI and ABS_LO is for llc -march=rvex -relocation-model=static (global // var in .data). case rvexII::MO_ABS_HI: Kind = MCSymbolRefExpr::VK_Cpu0_ABS_HI; break; case rvexII::MO_ABS_LO: Kind = MCSymbolRefExpr::VK_Cpu0_ABS_LO; break; } switch (MOTy) { case MachineOperand::MO_GlobalAddress: Symbol = Mang->getSymbol(MO.getGlobal()); 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 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()); } } }
void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { const TargetRegisterInfo &RI = *TM.getRegisterInfo(); switch (MO.getType()) { case MachineOperand::MO_Register: O << RI.get(MO.getReg()).AsmName; return; case MachineOperand::MO_Immediate: llvm_unreachable("printOp() does not handle immediate values"); return; case MachineOperand::MO_MachineBasicBlock: printBasicBlockLabel(MO.getMBB()); return; case MachineOperand::MO_ConstantPoolIndex: O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" << MO.getIndex(); return; case MachineOperand::MO_ExternalSymbol: O << MO.getSymbolName(); return; case MachineOperand::MO_GlobalAddress: O << Mang->getMangledName(MO.getGlobal()); return; case MachineOperand::MO_JumpTableIndex: O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << MO.getIndex(); return; default: O << "<unknown operand type: " << MO.getType() << ">"; return; } }
void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { 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 "; printReg(Op.getReg(), OS, TRI); // TODO: Print sub register. break; case MachineOperand::MO_Immediate: OS << Op.getImm(); break; case MachineOperand::MO_MachineBasicBlock: printMBBReference(*Op.getMBB()); break; case MachineOperand::MO_GlobalAddress: Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); // TODO: Print offset and target flags. 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; } default: // TODO: Print the other machine operands. llvm_unreachable("Can't print this machine operand at the moment"); } }