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); }
/// 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; }
/// 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; }
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; }
/// 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; }
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_CALL: Kind = RISCVMCExpr::VK_RISCV_CALL; break; case RISCVII::MO_LO: Kind = RISCVMCExpr::VK_RISCV_LO; break; case RISCVII::MO_HI: Kind = RISCVMCExpr::VK_RISCV_HI; break; case RISCVII::MO_PCREL_LO: Kind = RISCVMCExpr::VK_RISCV_PCREL_LO; break; case RISCVII::MO_PCREL_HI: Kind = RISCVMCExpr::VK_RISCV_PCREL_HI; break; } const MCExpr *ME = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) ME = MCBinaryExpr::createAdd( ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); if (Kind != RISCVMCExpr::VK_RISCV_None) ME = RISCVMCExpr::create(ME, Kind, Ctx); return MCOperand::createExpr(ME); }
MCOperand X86MCInstLower::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 = 0; MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None; switch (MO.getTargetFlags()) { default: llvm_unreachable("Unknown target flag on GV operand"); case X86II::MO_NO_FLAG: // No flag. // These affect the name of the symbol, not any suffix. case X86II::MO_DARWIN_NONLAZY: case X86II::MO_DLLIMPORT: case X86II::MO_DARWIN_STUB: break; case X86II::MO_TLVP: RefKind = MCSymbolRefExpr::VK_TLVP; break; case X86II::MO_TLVP_PIC_BASE: Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx); // Subtract the pic base. Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(MF.getPICBaseSymbol(), Ctx), Ctx); break; case X86II::MO_SECREL: RefKind = MCSymbolRefExpr::VK_SECREL; break; case X86II::MO_TLSGD: RefKind = MCSymbolRefExpr::VK_TLSGD; break; case X86II::MO_TLSLD: RefKind = MCSymbolRefExpr::VK_TLSLD; break; case X86II::MO_TLSLDM: RefKind = MCSymbolRefExpr::VK_TLSLDM; break; case X86II::MO_GOTTPOFF: RefKind = MCSymbolRefExpr::VK_GOTTPOFF; break; case X86II::MO_INDNTPOFF: RefKind = MCSymbolRefExpr::VK_INDNTPOFF; break; case X86II::MO_TPOFF: RefKind = MCSymbolRefExpr::VK_TPOFF; break; case X86II::MO_DTPOFF: RefKind = MCSymbolRefExpr::VK_DTPOFF; break; case X86II::MO_NTPOFF: RefKind = MCSymbolRefExpr::VK_NTPOFF; break; case X86II::MO_GOTNTPOFF: RefKind = MCSymbolRefExpr::VK_GOTNTPOFF; break; case X86II::MO_GOTPCREL: RefKind = MCSymbolRefExpr::VK_GOTPCREL; break; case X86II::MO_GOT: RefKind = MCSymbolRefExpr::VK_GOT; break; case X86II::MO_GOTOFF: RefKind = MCSymbolRefExpr::VK_GOTOFF; break; case X86II::MO_PLT: RefKind = MCSymbolRefExpr::VK_PLT; break; case X86II::MO_PIC_BASE_OFFSET: case X86II::MO_DARWIN_NONLAZY_PIC_BASE: case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: Expr = MCSymbolRefExpr::Create(Sym, Ctx); // Subtract the pic base. Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(MF.getPICBaseSymbol(), Ctx), Ctx); if (MO.isJTI() && MAI.hasSetDirective()) { // If .set directive is supported, use it to reduce the number of // relocations the assembler will generate for differences between // local labels. This is only safe when the symbols are in the same // section so we are restricting it to jumptable references. MCSymbol *Label = Ctx.CreateTempSymbol(); AsmPrinter.OutStreamer.EmitAssignment(Label, Expr); Expr = MCSymbolRefExpr::Create(Label, Ctx); } break; } if (Expr == 0) Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx); if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(MO.getOffset(), Ctx), Ctx); return MCOperand::CreateExpr(Expr); }
unsigned AlphaCodeEmitter::getMachineOpValue(const MachineInstr &MI, const MachineOperand &MO) { unsigned rv = 0; // Return value; defaults to 0 for unhandled cases // or things that get fixed up later by the JIT. if (MO.isReg()) { rv = getAlphaRegNumber(MO.getReg()); } else if (MO.isImm()) { rv = MO.getImm(); } else if (MO.isGlobal() || MO.isSymbol() || MO.isCPI()) { 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.isGlobal()) MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, MO.getGlobal(), Offset, isa<Function>(MO.getGlobal()), useGOT)); else if (MO.isSymbol()) 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.isMBB()) { MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), Alpha::reloc_bsr, MO.getMBB())); }else { cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; abort(); } return rv; }
static bool isValidDispOp(const MachineOperand &MO) { return MO.isImm() || MO.isCPI() || MO.isJTI() || MO.isSymbol() || MO.isGlobal() || MO.isBlockAddress() || MO.isMCSymbol() || MO.isMBB(); }