diff options
Diffstat (limited to 'contrib/llvm/lib/Target/PowerPC')
6 files changed, 44 insertions, 10 deletions
diff --git a/contrib/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/contrib/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp index 26869f250823..cce239cac970 100644 --- a/contrib/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ b/contrib/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -61,6 +61,14 @@ extern "C" void LLVMInitializePowerPCDisassembler() { createPPCLEDisassembler); } +static DecodeStatus DecodePCRel24BranchTarget(MCInst &Inst, unsigned Imm, + uint64_t Addr, + const void *Decoder) { + int32_t Offset = SignExtend32<24>(Imm); + Inst.addOperand(MCOperand::createImm(Offset)); + return MCDisassembler::Success; +} + // FIXME: These can be generated by TableGen from the existing register // encoding values! diff --git a/contrib/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp b/contrib/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp index fc29e4effbb1..6824168b890d 100644 --- a/contrib/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp +++ b/contrib/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp @@ -382,8 +382,11 @@ void PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo, // Branches can take an immediate operand. This is used by the branch // selection pass to print .+8, an eight byte displacement from the PC. - O << ".+"; - printAbsBranchOperand(MI, OpNo, O); + O << "."; + int32_t Imm = SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2); + if (Imm >= 0) + O << "+"; + O << Imm; } void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo, diff --git a/contrib/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/contrib/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp index a1e4e07b25af..78609ef3d4e0 100644 --- a/contrib/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ b/contrib/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -15,6 +15,7 @@ #include "InstPrinter/PPCInstPrinter.h" #include "MCTargetDesc/PPCMCAsmInfo.h" #include "PPCTargetStreamer.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/BinaryFormat/ELF.h" @@ -182,16 +183,33 @@ public: void emitAssignment(MCSymbol *S, const MCExpr *Value) override { auto *Symbol = cast<MCSymbolELF>(S); + // When encoding an assignment to set symbol A to symbol B, also copy // the st_other bits encoding the local entry point offset. - if (Value->getKind() != MCExpr::SymbolRef) - return; - const auto &RhsSym = cast<MCSymbolELF>( - static_cast<const MCSymbolRefExpr *>(Value)->getSymbol()); - unsigned Other = Symbol->getOther(); + if (copyLocalEntry(Symbol, Value)) + UpdateOther.insert(Symbol); + else + UpdateOther.erase(Symbol); + } + + void finish() override { + for (auto *Sym : UpdateOther) + copyLocalEntry(Sym, Sym->getVariableValue()); + } + +private: + SmallPtrSet<MCSymbolELF *, 32> UpdateOther; + + bool copyLocalEntry(MCSymbolELF *D, const MCExpr *S) { + auto *Ref = dyn_cast<const MCSymbolRefExpr>(S); + if (!Ref) + return false; + const auto &RhsSym = cast<MCSymbolELF>(Ref->getSymbol()); + unsigned Other = D->getOther(); Other &= ~ELF::STO_PPC64_LOCAL_MASK; Other |= RhsSym.getOther() & ELF::STO_PPC64_LOCAL_MASK; - Symbol->setOther(Other); + D->setOther(Other); + return true; } }; diff --git a/contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 31acd0ff870f..70e9049a2ab3 100644 --- a/contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/contrib/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -4359,8 +4359,8 @@ void PPCDAGToDAGISel::Select(SDNode *N) { const Module *M = MF->getFunction().getParent(); if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) != MVT::i32 || - !PPCSubTarget->isSecurePlt() || !PPCSubTarget->isTargetELF() || - M->getPICLevel() == PICLevel::SmallPIC) + (!TM.isPositionIndependent() || !PPCSubTarget->isSecurePlt()) || + !PPCSubTarget->isTargetELF() || M->getPICLevel() == PICLevel::SmallPIC) break; SDValue Op = N->getOperand(1); diff --git a/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.td index dd3f1ac79089..77aa4fe3d415 100644 --- a/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/contrib/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -737,7 +737,9 @@ def abscondbrtarget : Operand<OtherVT> { def calltarget : Operand<iPTR> { let PrintMethod = "printBranchOperand"; let EncoderMethod = "getDirectBrEncoding"; + let DecoderMethod = "DecodePCRel24BranchTarget"; let ParserMatchClass = PPCDirectBrAsmOperand; + let OperandType = "OPERAND_PCREL"; } def abscalltarget : Operand<iPTR> { let PrintMethod = "printAbsBranchOperand"; diff --git a/contrib/llvm/lib/Target/PowerPC/PPCSubtarget.cpp b/contrib/llvm/lib/Target/PowerPC/PPCSubtarget.cpp index c0cbfd779cb9..1fdf74549dec 100644 --- a/contrib/llvm/lib/Target/PowerPC/PPCSubtarget.cpp +++ b/contrib/llvm/lib/Target/PowerPC/PPCSubtarget.cpp @@ -138,6 +138,9 @@ void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) { if (isDarwin()) HasLazyResolverStubs = true; + if (TargetTriple.isOSNetBSD() || TargetTriple.isOSOpenBSD()) + SecurePlt = true; + if (HasSPE && IsPPC64) report_fatal_error( "SPE is only supported for 32-bit targets.\n", false); if (HasSPE && (HasAltivec || HasQPX || HasVSX || HasFPU)) |