MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol) { MCSymbolRefExpr::VariantKind SymbolVariant = MCSymbolRefExpr::VK_None; if (MO.getTargetFlags() & ARMII::MO_SBREL) SymbolVariant = MCSymbolRefExpr::VK_ARM_SBREL; const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, SymbolVariant, OutContext); switch (MO.getTargetFlags() & ARMII::MO_OPTION_MASK) { default: llvm_unreachable("Unknown target flag on symbol operand"); case ARMII::MO_NO_FLAG: break; case ARMII::MO_LO16: Expr = MCSymbolRefExpr::create(Symbol, SymbolVariant, OutContext); Expr = ARMMCExpr::createLower16(Expr, OutContext); break; case ARMII::MO_HI16: Expr = MCSymbolRefExpr::create(Symbol, SymbolVariant, OutContext); Expr = ARMMCExpr::createUpper16(Expr, OutContext); break; } if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(MO.getOffset(), OutContext), OutContext); return MCOperand::createExpr(Expr); }
static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, AsmPrinter &Printer, bool isDarwin) { MCContext &Ctx = Printer.OutContext; MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None; if (MO.getTargetFlags() & PPCII::MO_LO16) RefKind = isDarwin ? MCSymbolRefExpr::VK_PPC_DARWIN_LO16 : MCSymbolRefExpr::VK_PPC_GAS_LO16; else if (MO.getTargetFlags() & PPCII::MO_HA16) RefKind = isDarwin ? MCSymbolRefExpr::VK_PPC_DARWIN_HA16 : MCSymbolRefExpr::VK_PPC_GAS_HA16; // FIXME: This isn't right, but we don't have a good way to express this in // the MC Level, see below. if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG) RefKind = MCSymbolRefExpr::VK_None; const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx); if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(MO.getOffset(), Ctx), Ctx); // Subtract off the PIC base if required. if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG) { const MachineFunction *MF = MO.getParent()->getParent()->getParent(); const MCExpr *PB = MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), Ctx); Expr = MCBinaryExpr::CreateSub(Expr, PB, Ctx); // FIXME: We have no way to make the result be VK_PPC_LO16/VK_PPC_HA16, // since it is not a symbol! } return MCOperand::CreateExpr(Expr); }
static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, AsmPrinter &Printer, bool isDarwin) { MCContext &Ctx = Printer.OutContext; MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None; unsigned access = MO.getTargetFlags() & PPCII::MO_ACCESS_MASK; switch (access) { case PPCII::MO_TPREL_LO: RefKind = MCSymbolRefExpr::VK_PPC_TPREL_LO; break; case PPCII::MO_TPREL_HA: RefKind = MCSymbolRefExpr::VK_PPC_TPREL_HA; break; case PPCII::MO_DTPREL_LO: RefKind = MCSymbolRefExpr::VK_PPC_DTPREL_LO; break; case PPCII::MO_TLSLD_LO: RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO; break; case PPCII::MO_TOC_LO: RefKind = MCSymbolRefExpr::VK_PPC_TOC_LO; break; case PPCII::MO_TLS: RefKind = MCSymbolRefExpr::VK_PPC_TLS; break; } if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB && !isDarwin) RefKind = MCSymbolRefExpr::VK_PLT; const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, RefKind, Ctx); if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); // Subtract off the PIC base if required. if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG) { const MachineFunction *MF = MO.getParent()->getParent()->getParent(); const MCExpr *PB = MCSymbolRefExpr::create(MF->getPICBaseSymbol(), Ctx); Expr = MCBinaryExpr::createSub(Expr, PB, Ctx); } // Add ha16() / lo16() markers if required. switch (access) { case PPCII::MO_LO: Expr = PPCMCExpr::createLo(Expr, isDarwin, Ctx); break; case PPCII::MO_HA: Expr = PPCMCExpr::createHa(Expr, isDarwin, Ctx); break; } return MCOperand::createExpr(Expr); }
void MachineOperand::printTargetFlags(raw_ostream &OS, const MachineOperand &Op) { if (!Op.getTargetFlags()) return; const MachineFunction *MF = getMFIfAvailable(Op); if (!MF) return; const auto *TII = MF->getSubtarget().getInstrInfo(); assert(TII && "expected instruction info"); auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags()); OS << "target-flags("; const bool HasDirectFlags = Flags.first; const bool HasBitmaskFlags = Flags.second; if (!HasDirectFlags && !HasBitmaskFlags) { OS << "<unknown>) "; return; } if (HasDirectFlags) { if (const auto *Name = getTargetFlagName(TII, Flags.first)) OS << Name; else OS << "<unknown target flag>"; } if (!HasBitmaskFlags) { OS << ") "; return; } bool IsCommaNeeded = HasDirectFlags; unsigned BitMask = Flags.second; auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags(); for (const auto &Mask : BitMasks) { // Check if the flag's bitmask has the bits of the current mask set. if ((BitMask & Mask.first) == Mask.first) { if (IsCommaNeeded) OS << ", "; IsCommaNeeded = true; OS << Mask.second; // Clear the bits which were serialized from the flag's bitmask. BitMask &= ~(Mask.first); } } if (BitMask) { // When the resulting flag's bitmask isn't zero, we know that we didn't // serialize all of the bit flags. if (IsCommaNeeded) OS << ", "; OS << "<unknown bitmask target flag>"; } OS << ") "; }
MCOperand AArch64MCInstLower::lowerSymbolOperandDarwin(const MachineOperand &MO, MCSymbol *Sym) const { // FIXME: We would like an efficient form for this, so we don't have to do a // lot of extra uniquing. MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None; if ((MO.getTargetFlags() & AArch64II::MO_GOT) != 0) { if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE) RefKind = MCSymbolRefExpr::VK_GOTPAGE; else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGEOFF) RefKind = MCSymbolRefExpr::VK_GOTPAGEOFF; else llvm_unreachable("Unexpected target flags with MO_GOT on GV operand"); } else if ((MO.getTargetFlags() & AArch64II::MO_TLS) != 0) { if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE) RefKind = MCSymbolRefExpr::VK_TLVPPAGE; else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGEOFF) RefKind = MCSymbolRefExpr::VK_TLVPPAGEOFF; else llvm_unreachable("Unexpected target flags with MO_TLS on GV operand"); } else { if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE) RefKind = MCSymbolRefExpr::VK_PAGE; else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGEOFF) RefKind = MCSymbolRefExpr::VK_PAGEOFF; } const MCExpr *Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx); if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::createAdd( Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); return MCOperand::createExpr(Expr); }
MCOperand AArch64MCInstLower::lowerSymbolOperandCOFF(const MachineOperand &MO, MCSymbol *Sym) const { uint32_t RefFlags = 0; if (MO.getTargetFlags() & AArch64II::MO_TLS) { if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGEOFF) RefFlags |= AArch64MCExpr::VK_SECREL_LO12; else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_HI12) RefFlags |= AArch64MCExpr::VK_SECREL_HI12; } else if (MO.getTargetFlags() & AArch64II::MO_S) { RefFlags |= AArch64MCExpr::VK_SABS; } else { RefFlags |= AArch64MCExpr::VK_ABS; } if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G3) RefFlags |= AArch64MCExpr::VK_G3; else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G2) RefFlags |= AArch64MCExpr::VK_G2; else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G1) RefFlags |= AArch64MCExpr::VK_G1; else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G0) RefFlags |= AArch64MCExpr::VK_G0; // FIXME: Currently we only set VK_NC for MO_G3/MO_G2/MO_G1/MO_G0. This is // because setting VK_NC for others would mean setting their respective // RefFlags correctly. We should do this in a separate patch. if (MO.getTargetFlags() & AArch64II::MO_NC) { auto MOFrag = (MO.getTargetFlags() & AArch64II::MO_FRAGMENT); if (MOFrag == AArch64II::MO_G3 || MOFrag == AArch64II::MO_G2 || MOFrag == AArch64II::MO_G1 || MOFrag == AArch64II::MO_G0) RefFlags |= AArch64MCExpr::VK_NC; } const MCExpr *Expr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::createAdd( Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); auto RefKind = static_cast<AArch64MCExpr::VariantKind>(RefFlags); assert(RefKind != AArch64MCExpr::VK_INVALID && "Invalid relocation requested"); Expr = AArch64MCExpr::create(Expr, RefKind, Ctx); return MCOperand::createExpr(Expr); }
void MIPrinter::printTargetFlags(const MachineOperand &Op) { if (!Op.getTargetFlags()) return; const auto *TII = Op.getParent()->getParent()->getParent()->getSubtarget().getInstrInfo(); assert(TII && "expected instruction info"); auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags()); OS << "target-flags("; if (const auto *Name = getTargetFlagName(TII, Flags.first)) OS << Name; else OS << "<unknown target flag>"; // TODO: Print the target's bit flags. OS << ") "; }
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()); }
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); }
static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, ARMAsmPrinter &Printer) { MCContext &Ctx = Printer.OutContext; const MCExpr *Expr; switch (MO.getTargetFlags()) { default: assert(0 && "Unknown target flag on symbol operand"); case 0: Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx); break; case ARMII::MO_LO16: Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_LO16, Ctx); break; case ARMII::MO_HI16: Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_HI16, Ctx); break; case ARMII::MO_PLT: Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT, Ctx); break; } if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(MO.getOffset(), Ctx), Ctx); return MCOperand::CreateExpr(Expr); }
static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym, const AsmPrinter &AP) { MCContext &Ctx = AP.OutContext; RISCVMCExpr::VariantKind Kind; switch (MO.getTargetFlags()) { default: llvm_unreachable("Unknown target flag on GV operand"); case RISCVII::MO_None: Kind = RISCVMCExpr::VK_RISCV_None; break; case RISCVII::MO_LO: Kind = RISCVMCExpr::VK_RISCV_LO; break; case RISCVII::MO_HI: Kind = RISCVMCExpr::VK_RISCV_HI; break; } const MCExpr *ME = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); if (!MO.isJTI() && MO.getOffset()) ME = MCBinaryExpr::createAdd( ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); ME = RISCVMCExpr::create(ME, Kind, Ctx); return MCOperand::createExpr(ME); }
/// 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 EpiphanyMCInstLower:: LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const { const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx); switch (MO.getTargetFlags()) { case EpiphanyII::MO_LO16: Expr = EpiphanyMCExpr::createLo16(Expr, Ctx); break; case EpiphanyII::MO_HI16: Expr = EpiphanyMCExpr::createHi16(Expr, Ctx); break; case EpiphanyII::MO_NO_FLAG: // Expr is already correct break; default: llvm_unreachable("Unexpected MachineOperand flag - lowersymboloperand"); } if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); return MCOperand::createExpr(Expr); }
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::COMBINE_rI_V4), 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::COMBINE_rI_V4), DoubleDestReg) .addReg(HiReg, HiRegKillFlag) .addImm(LoOperand.getImm()); }
MCOperand LanaiMCInstLower::LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const { LanaiMCExpr::VariantKind Kind; switch (MO.getTargetFlags()) { case LanaiII::MO_NO_FLAG: Kind = LanaiMCExpr::VK_Lanai_None; break; case LanaiII::MO_ABS_HI: Kind = LanaiMCExpr::VK_Lanai_ABS_HI; break; case LanaiII::MO_ABS_LO: Kind = LanaiMCExpr::VK_Lanai_ABS_LO; break; default: llvm_unreachable("Unknown target flag on GV operand"); } const MCExpr *Expr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::createAdd( Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); Expr = LanaiMCExpr::create(Kind, Expr, Ctx); return MCOperand::createExpr(Expr); }
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()); }
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 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; }
MCOperand SystemZMCInstLower::lowerSymbolOperand(const MachineOperand &MO, const MCSymbol *Symbol, int64_t Offset) const { MCSymbolRefExpr::VariantKind Kind = getVariantKind(MO.getTargetFlags()); const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, Kind, Ctx); if (Offset) { const MCExpr *OffsetExpr = MCConstantExpr::Create(Offset, Ctx); Expr = MCBinaryExpr::CreateAdd(Expr, OffsetExpr, Ctx); } return MCOperand::CreateExpr(Expr); }
MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol) { const MCExpr *Expr; switch (MO.getTargetFlags()) { default: { Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, OutContext); switch (MO.getTargetFlags()) { default: assert(0 && "Unknown target flag on symbol operand"); case 0: break; case ARMII::MO_LO16: Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, OutContext); Expr = ARMMCExpr::CreateLower16(Expr, OutContext); break; case ARMII::MO_HI16: Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, OutContext); Expr = ARMMCExpr::CreateUpper16(Expr, OutContext); break; } break; } case ARMII::MO_PLT: Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT, OutContext); break; } if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(MO.getOffset(), OutContext), OutContext); return MCOperand::CreateExpr(Expr); }
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 SystemZMCInstLower::lowerOperand(const MachineOperand &MO) const { switch (MO.getType()) { case MachineOperand::MO_Register: return MCOperand::CreateReg(MO.getReg()); case MachineOperand::MO_Immediate: return MCOperand::CreateImm(MO.getImm()); default: { MCSymbolRefExpr::VariantKind Kind = getVariantKind(MO.getTargetFlags()); return MCOperand::CreateExpr(getExpr(MO, Kind)); } } }
MCOperand MSP430MCInstLower:: LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const { // FIXME: We would like an efficient form for this, so we don't have to do a // lot of extra uniquing. const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx); switch (MO.getTargetFlags()) { default: llvm_unreachable("Unknown target flag on GV operand"); case 0: break; } if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(MO.getOffset(), Ctx), Ctx); return MCOperand::CreateExpr(Expr); }
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); }
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 WebAssemblyMCInstLower::lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const { MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; unsigned TargetFlags = MO.getTargetFlags(); switch (TargetFlags) { case WebAssemblyII::MO_NO_FLAG: break; case WebAssemblyII::MO_GOT: Kind = MCSymbolRefExpr::VK_GOT; break; case WebAssemblyII::MO_MEMORY_BASE_REL: Kind = MCSymbolRefExpr::VK_WASM_MBREL; break; case WebAssemblyII::MO_TABLE_BASE_REL: Kind = MCSymbolRefExpr::VK_WASM_TBREL; break; default: llvm_unreachable("Unknown target flag on GV operand"); } const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Kind, Ctx); if (MO.getOffset() != 0) { const auto *WasmSym = cast<MCSymbolWasm>(Sym); if (TargetFlags == WebAssemblyII::MO_GOT) report_fatal_error("GOT symbol references do not support offsets"); if (WasmSym->isFunction()) report_fatal_error("Function addresses with offsets not supported"); if (WasmSym->isGlobal()) report_fatal_error("Global indexes with offsets not supported"); if (WasmSym->isEvent()) report_fatal_error("Event indexes with offsets not supported"); Expr = MCBinaryExpr::createAdd( Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); } return MCOperand::createExpr(Expr); }
MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol) { const MCExpr *Expr; unsigned Option = MO.getTargetFlags() & ARMII::MO_OPTION_MASK; switch (Option) { default: { Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, OutContext); switch (Option) { default: llvm_unreachable("Unknown target flag on symbol operand"); case ARMII::MO_NO_FLAG: break; case ARMII::MO_LO16: Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, OutContext); Expr = ARMMCExpr::CreateLower16(Expr, OutContext); break; case ARMII::MO_HI16: Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, OutContext); Expr = ARMMCExpr::CreateUpper16(Expr, OutContext); break; } break; } case ARMII::MO_PLT: Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_PLT, OutContext); break; } if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(MO.getOffset(), OutContext), OutContext); return MCOperand::CreateExpr(Expr); }
MCOperand VideocoreMCInstLower::LowerSymbolOperand(const MachineOperand &MO, MachineOperandType MOTy, unsigned Offset) const { assert(Ctx != NULL); MCSymbolRefExpr::VariantKind Kind; const MCSymbol *Symbol; switch(MO.getTargetFlags()) { default: llvm_unreachable("Invalid target flag!"); case VideocoreII::MO_NO_FLAG: Kind = MCSymbolRefExpr::VK_None; break; } switch (MOTy) { case MachineOperand::MO_MachineBasicBlock: Symbol = MO.getMBB()->getSymbol(); break; 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); }
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); }