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); }
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; } }
/// 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(); } }
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); }
/// 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; }
/// 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; }
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()); }
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; }
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; }
// 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"); }
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; }
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 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; } }
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; }
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); }
void AlphaAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) { switch (MO.getType()) { case MachineOperand::MO_Register: O << getRegisterName(MO.getReg()); return; case MachineOperand::MO_Immediate: assert(0 && "printOp() does not handle immediate values"); return; case MachineOperand::MO_MachineBasicBlock: O << *MO.getMBB()->getSymbol(); return; case MachineOperand::MO_ConstantPoolIndex: O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" << MO.getIndex(); return; case MachineOperand::MO_ExternalSymbol: O << MO.getSymbolName(); return; case MachineOperand::MO_GlobalAddress: O << *Mang->getSymbol(MO.getGlobal()); return; case MachineOperand::MO_JumpTableIndex: O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << MO.getIndex(); return; default: O << "<unknown operand type: " << MO.getType() << ">"; return; } }
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, 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; } } }
void IA64AsmPrinter::printOp(const MachineOperand &MO, bool isBRCALLinsn /* = false */) { const TargetRegisterInfo &RI = *TM.getRegisterInfo(); switch (MO.getType()) { case MachineOperand::MO_Register: O << RI.get(MO.getReg()).AsmName; return; case MachineOperand::MO_Immediate: O << MO.getImm(); return; case MachineOperand::MO_MachineBasicBlock: printBasicBlockLabel(MO.getMBB()); return; case MachineOperand::MO_ConstantPoolIndex: { O << "@gprel(" << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" << MO.getIndex() << ")"; return; } case MachineOperand::MO_GlobalAddress: { // functions need @ltoff(@fptr(fn_name)) form GlobalValue *GV = MO.getGlobal(); Function *F = dyn_cast<Function>(GV); bool Needfptr=false; // if we're computing an address @ltoff(X), do // we need to decorate it so it becomes // @ltoff(@fptr(X)) ? if (F && !isBRCALLinsn /*&& F->isDeclaration()*/) Needfptr=true; // if this is the target of a call instruction, we should define // the function somewhere (GNU gas has no problem without this, but // Intel ias rightly complains of an 'undefined symbol') if (F /*&& isBRCALLinsn*/ && F->isDeclaration()) ExternalFunctionNames.insert(Mang->getValueName(MO.getGlobal())); else if (GV->isDeclaration()) // e.g. stuff like 'stdin' ExternalObjectNames.insert(Mang->getValueName(MO.getGlobal())); if (!isBRCALLinsn) O << "@ltoff("; if (Needfptr) O << "@fptr("; O << Mang->getValueName(MO.getGlobal()); if (Needfptr && !isBRCALLinsn) O << "#))"; // close both fptr( and ltoff( else { if (Needfptr) O << "#)"; // close only fptr( if (!isBRCALLinsn) O << "#)"; // close only ltoff( } int Offset = MO.getOffset(); if (Offset > 0) O << " + " << Offset; else if (Offset < 0) O << " - " << -Offset; return; } case MachineOperand::MO_ExternalSymbol: O << MO.getSymbolName(); ExternalFunctionNames.insert(MO.getSymbolName()); return; default: O << "<AsmPrinter: unknown operand type: " << MO.getType() << " >"; return; } }
int AlphaCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { int rv = 0; // Return value; defaults to 0 for unhandled cases // or things that get fixed up later by the JIT. if (MO.isRegister()) { rv = getAlphaRegNumber(MO.getReg()); } else if (MO.isImmediate()) { rv = MO.getImm(); } else if (MO.isGlobalAddress() || MO.isExternalSymbol() || MO.isConstantPoolIndex()) { DOUT << MO << " is a relocated op for " << MI << "\n"; unsigned Reloc = 0; int Offset = 0; bool useGOT = false; switch (MI.getOpcode()) { case Alpha::BSR: Reloc = Alpha::reloc_bsr; break; case Alpha::LDLr: case Alpha::LDQr: case Alpha::LDBUr: case Alpha::LDWUr: case Alpha::LDSr: case Alpha::LDTr: case Alpha::LDAr: case Alpha::STQr: case Alpha::STLr: case Alpha::STWr: case Alpha::STBr: case Alpha::STSr: case Alpha::STTr: Reloc = Alpha::reloc_gprellow; break; case Alpha::LDAHr: Reloc = Alpha::reloc_gprelhigh; break; case Alpha::LDQl: Reloc = Alpha::reloc_literal; useGOT = true; break; case Alpha::LDAg: case Alpha::LDAHg: Reloc = Alpha::reloc_gpdist; Offset = MI.getOperand(3).getImm(); break; default: assert(0 && "unknown relocatable instruction"); abort(); } if (MO.isGlobalAddress()) MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, MO.getGlobal(), Offset, isa<Function>(MO.getGlobal()), useGOT)); else if (MO.isExternalSymbol()) MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), Reloc, MO.getSymbolName(), Offset, true)); else MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), Reloc, MO.getIndex(), Offset)); } else if (MO.isMachineBasicBlock()) { MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), Alpha::reloc_bsr, MO.getMBB())); }else { cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; abort(); } return rv; }