Index: llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
===================================================================
--- llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -356,6 +356,12 @@
   bool isS16ImmX16() const { return Kind == Expression ||
                                     (Kind == Immediate && isInt<16>(getImm()) &&
                                      (getImm() & 15) == 0); }
+  bool isS34Imm() const {
+    // Once the PC-Rel ABI is finalized, evaluate whether a 34-bit
+    // ContextImmediate is needed.
+    return Kind == Expression || (Kind == Immediate && isInt<34>(getImm()));
+  }
+
   bool isS17Imm() const {
     switch (Kind) {
       case Expression:
@@ -388,6 +394,7 @@
   bool isCondBr() const { return Kind == Expression ||
                                  (Kind == Immediate && isInt<16>(getImm()) &&
                                   (getImm() & 3) == 0); }
+  bool isImmZero() const { return Kind == Immediate && getImm() == 0; }
   bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }
   bool isVSRegNumber() const {
     return Kind == Immediate && isUInt<6>(getImm());
Index: llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
===================================================================
--- llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
+++ llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
@@ -192,6 +192,14 @@
   return MCDisassembler::Success;
 }
 
+static DecodeStatus decodeImmZeroOperand(MCInst &Inst, uint64_t Imm,
+                                         int64_t Address, const void *Decoder) {
+  if (Imm != 0)
+    return MCDisassembler::Fail;
+  Inst.addOperand(MCOperand::createImm(Imm));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm,
                                         int64_t Address, const void *Decoder) {
   // Decode the memri field (imm, reg), which has the low 16-bits as the
@@ -325,6 +333,29 @@
                                              ArrayRef<uint8_t> Bytes,
                                              uint64_t Address, raw_ostream &OS,
                                              raw_ostream &CS) const {
+  auto *ReadFunc = IsLittleEndian ? support::endian::read32le
+                                  : support::endian::read32be;
+
+  // If this is an 8-byte prefixed instruction, handle it here.
+  // Note: prefixed instructions aren't technically 8-byte entities - the prefix
+  //       appears in memory at an address 4 bytes prior to that of the base
+  //       instruction regardless of endianness. So we read the two pieces and
+  //       rebuild the 8-byte instruction.
+  // TODO: In this function we call decodeInstruction several times with
+  //       different decoder tables. It may be possible to only call once by
+  //       looking at the top 6 bits of the instruction.
+  if (STI.getFeatureBits()[PPC::FeaturePrefixInstrs] && Bytes.size() >= 8) {
+    uint32_t Prefix = ReadFunc(Bytes.data());
+    uint32_t BaseInst = ReadFunc(Bytes.data() + 4);
+    uint64_t Inst = BaseInst | (uint64_t)Prefix << 32;
+    DecodeStatus result = decodeInstruction(DecoderTable64, MI, Inst, Address,
+                                            this, STI);
+    if (result != MCDisassembler::Fail) {
+      Size = 8;
+      return result;
+    }
+  }
+
   // Get the four bytes of the instruction.
   Size = 4;
   if (Bytes.size() < 4) {
@@ -333,8 +364,7 @@
   }
 
   // Read the instruction in the proper endianness.
-  uint32_t Inst = IsLittleEndian ? support::endian::read32le(Bytes.data())
-                                 : support::endian::read32be(Bytes.data());
+  uint64_t Inst = ReadFunc(Bytes.data());
 
   if (STI.getFeatureBits()[PPC::FeatureQPX]) {
     DecodeStatus result =
Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
===================================================================
--- llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
+++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
@@ -61,7 +61,9 @@
   void printU10ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printU12ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printS16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+  void printS34ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printU16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+  void printImmZeroOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printAbsBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printTLSCall(const MCInst *MI, unsigned OpNo, raw_ostream &O);
Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
===================================================================
--- llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
+++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
@@ -339,6 +339,13 @@
   O << (int)Value;
 }
 
+void PPCInstPrinter::printImmZeroOperand(const MCInst *MI, unsigned OpNo,
+                                         raw_ostream &O) {
+  unsigned int Value = MI->getOperand(OpNo).getImm();
+  assert(Value == 0 && "Operand must be zero");
+  O << (unsigned int)Value;
+}
+
 void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
                                        raw_ostream &O) {
   unsigned int Value = MI->getOperand(OpNo).getImm();
@@ -391,6 +398,13 @@
     printOperand(MI, OpNo, O);
 }
 
+void PPCInstPrinter::printS34ImmOperand(const MCInst *MI, unsigned OpNo,
+                                        raw_ostream &O) {
+  long long Value = MI->getOperand(OpNo).getImm();
+  assert(isInt<34>(Value) && "Invalid s34imm argument!");
+  O << (long long)Value;
+}
+
 void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
                                         raw_ostream &O) {
   if (MI->getOperand(OpNo).isImm())
Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h
===================================================================
--- llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h
+++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h
@@ -80,7 +80,7 @@
 
   /// getMachineOpValue - Return binary encoding of operand. If the machine
   /// operand requires relocation, record the relocation and return zero.
-  unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
+  uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
                              SmallVectorImpl<MCFixup> &Fixups,
                              const MCSubtargetInfo &STI) const;
 
Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
===================================================================
--- llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
+++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
@@ -257,7 +257,7 @@
   return ~0U; // Silence any warnings about no return.
 }
 
-unsigned PPCMCCodeEmitter::
+uint64_t PPCMCCodeEmitter::
 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
                   SmallVectorImpl<MCFixup> &Fixups,
                   const MCSubtargetInfo &STI) const {
Index: llvm/lib/Target/PowerPC/PPC.td
===================================================================
--- llvm/lib/Target/PowerPC/PPC.td
+++ llvm/lib/Target/PowerPC/PPC.td
@@ -209,6 +209,11 @@
                                                  "VectorsUseTwoUnits",
                                                  "true",
                                                  "Vectors use two units">;
+def FeaturePrefixInstrs : SubtargetFeature<"prefix-instrs", "HasPrefixInstrs",
+                                           "true",
+                                           "Enable prefixed instructions",
+                                           [FeatureISA3_0, FeatureP8Vector,
+                                            FeatureP9Altivec]>;
 
 // Since new processors generally contain a superset of features of those that
 // came before them, the idea is to make implementations of new processors
@@ -298,7 +303,7 @@
   // For future CPU we assume that all of the existing features from Power 9
   // still exist with the exception of those we know are Power 9 specific.
   list<SubtargetFeature> FutureAdditionalFeatures = [];
-  list<SubtargetFeature> FutureSpecificFeatures = [];
+  list<SubtargetFeature> FutureSpecificFeatures = [FeaturePrefixInstrs];
   list<SubtargetFeature> FutureInheritableFeatures =
     !listconcat(P9InheritableFeatures, FutureAdditionalFeatures);
   list<SubtargetFeature> FutureFeatures =
Index: llvm/lib/Target/PowerPC/PPCInstrFormats.td
===================================================================
--- llvm/lib/Target/PowerPC/PPCInstrFormats.td
+++ llvm/lib/Target/PowerPC/PPCInstrFormats.td
@@ -41,6 +41,14 @@
   bits<1> XFormMemOp = 0;
   let TSFlags{7}  = XFormMemOp;
 
+  // Indicate that this instruction does not use the default register numbering.
+  bits<1> UseCustomRegNumbering = 0;
+  let TSFlags{8}  = UseCustomRegNumbering;
+
+  // Indicate that this instruction is prefixed.
+  bits<1> Prefixed = 0;
+  let TSFlags{9}  = Prefixed;
+
   // Fields used for relation models.
   string BaseName = "";
 
Index: llvm/lib/Target/PowerPC/PPCInstrInfo.h
===================================================================
--- llvm/lib/Target/PowerPC/PPCInstrInfo.h
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.h
@@ -65,7 +65,11 @@
   NewDef_Shift = 6,
 
   /// This instruction is an X-Form memory operation.
-  XFormMemOp = 0x1 << (NewDef_Shift+1)
+  XFormMemOp = 0x1 << (NewDef_Shift+1),
+  /// This instruction uses the default register numbering.
+  UseCustomRegNumbering = 0x1 << (NewDef_Shift+2),
+  /// This instruction is prefixed.
+  Prefixed = 0x1 << (NewDef_Shift+3)
 };
 } // end namespace PPCII
 
Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
===================================================================
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -723,6 +723,26 @@
   let ParserMatchClass = PPCS17ImmAsmOperand;
   let DecoderMethod = "decodeSImmOperand<16>";
 }
+def PPCS34ImmAsmOperand : AsmOperandClass {
+  let Name = "S34Imm";
+  let PredicateMethod = "isS34Imm";
+  let RenderMethod = "addImmOperands";
+}
+def s34imm : Operand<i64> {
+  let PrintMethod = "printS34ImmOperand";
+  let ParserMatchClass = PPCS34ImmAsmOperand;
+  let DecoderMethod = "decodeSImmOperand<34>";
+}
+def PPCImmZeroAsmOperand : AsmOperandClass {
+  let Name = "ImmZero";
+  let PredicateMethod = "isImmZero";
+  let RenderMethod = "addImmOperands";
+}
+def immZero : Operand<i32> {
+  let PrintMethod = "printImmZeroOperand";
+  let ParserMatchClass = PPCImmZeroAsmOperand;
+  let DecoderMethod = "decodeImmZeroOperand";
+}
 
 def fpimm0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>;
 
@@ -3331,6 +3351,10 @@
 def       : Pat<(not i1:$in),
                 (crnot $in)>;
 
+// Prefixed instructions may requre access to the above defs at a later
+// time so we include this after the def.
+include "PPCInstrPrefix.td"
+
 // Patterns for arithmetic i1 operations.
 def : Pat<(add i1:$a, i1:$b),
           (CRXOR $a, $b)>;
Index: llvm/lib/Target/PowerPC/PPCInstrPrefix.td
===================================================================
--- /dev/null
+++ llvm/lib/Target/PowerPC/PPCInstrPrefix.td
@@ -0,0 +1,126 @@
+// PC Relative flag (for instructions that use the address of the prefix for
+// address computations).
+class isPCRel { bit PCRel = 1; }
+
+// Top-level class for prefixed instructions.
+class PI<bits<6> pref, bits<6> opcode, dag OOL, dag IOL, string asmstr,
+         InstrItinClass itin> : Instruction {
+  field bits<64> Inst;
+  field bits<64> SoftFail = 0;
+  bit PCRel = 0; // Default value, set by isPCRel.
+  let Size = 8;
+
+  let Namespace = "PPC";
+  let OutOperandList = OOL;
+  let InOperandList = IOL;
+  let AsmString = asmstr;
+  let Itinerary = itin;
+  let Inst{0-5} = pref;
+  let Inst{32-37} = opcode;
+
+  bits<1> PPC970_First = 0;
+  bits<1> PPC970_Single = 0;
+  bits<1> PPC970_Cracked = 0;
+  bits<3> PPC970_Unit = 0;
+
+  /// These fields correspond to the fields in PPCInstrInfo.h.  Any changes to
+  /// these must be reflected there!  See comments there for what these are.
+  let TSFlags{0}   = PPC970_First;
+  let TSFlags{1}   = PPC970_Single;
+  let TSFlags{2}   = PPC970_Cracked;
+  let TSFlags{5-3} = PPC970_Unit;
+
+  bits<1> UseCustomRegNumbering = 0;
+  let TSFlags{8} = UseCustomRegNumbering;
+
+  bits<1> Prefixed = 1;  // This is a prefixed instruction.
+  let TSFlags{9}  = Prefixed;
+
+  // For cases where multiple instruction definitions really represent the
+  // same underlying instruction but with one definition for 64-bit arguments
+  // and one for 32-bit arguments, this bit breaks the degeneracy between
+  // the two forms and allows TableGen to generate mapping tables.
+  bit Interpretation64Bit = 0;
+
+  // Fields used for relation models.
+  string BaseName = "";
+}
+
+class MLS_DForm_R_SI34_RTA5<bits<6> opcode, dag OOL, dag IOL, string asmstr,
+                            InstrItinClass itin, list<dag> pattern>
+  : PI<1, opcode, OOL, IOL, asmstr, itin> {
+  bits<5> RT;
+  bits<5> RA;
+  bits<34> SI;
+
+  let Pattern = pattern;
+
+  // The prefix.
+  let Inst{6-7} = 2;
+  let Inst{8-10} = 0;
+  let Inst{11} = PCRel;
+  let Inst{12-13} = 0;
+  let Inst{14-31} = SI{33-16};
+
+  // The instruction.
+  let Inst{38-42} = RT;
+  let Inst{43-47} = RA;
+  let Inst{48-63} = SI{15-0};
+}
+
+class MLS_DForm2_r0<bits<6> opcode, dag OOL, dag IOL, string asmstr,
+                    InstrItinClass itin, list<dag> pattern>
+  : PI<1, opcode, OOL, IOL, asmstr, itin> {
+  bits<5> RT;
+  bits<34> SI;
+
+  let Pattern = pattern;
+
+  // The prefix.
+  let Inst{6-7} = 2;
+  let Inst{8-10} = 0;
+  let Inst{11} = 0;
+  let Inst{12-13} = 0;
+  let Inst{14-31} = SI{33-16};
+
+  // The instruction.
+  let Inst{38-42} = RT;
+  let Inst{43-47} = 0;
+  let Inst{48-63} = SI{15-0};
+}
+
+multiclass MLS_DForm_R_SI34_RTA5_p<bits<6> opcode, dag OOL, dag IOL,
+                                   dag PCRel_IOL, string asmstr,
+                                   InstrItinClass itin> {
+  def NAME : MLS_DForm_R_SI34_RTA5<opcode, OOL, IOL,
+                                   !strconcat(asmstr, ", 0"), itin, []>;
+  def pc : MLS_DForm_R_SI34_RTA5<opcode, OOL, PCRel_IOL,
+                                 !strconcat(asmstr, ", 1"), itin, []>, isPCRel;
+}
+
+
+def PrefixInstrs : Predicate<"PPCSubTarget->hasPrefixInstrs()">;
+
+let Predicates = [PrefixInstrs] in {
+  let Interpretation64Bit = 1, isCodeGenOnly = 1 in {
+    defm PADDI8 :
+      MLS_DForm_R_SI34_RTA5_p<14, (outs g8rc:$RT), (ins g8rc:$RA, s34imm:$SI),
+                              (ins immZero:$RA, s34imm:$SI),
+                              "paddi $RT, $RA, $SI", IIC_LdStLFD>;
+    let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
+      def PLI8 : MLS_DForm2_r0<14, (outs g8rc:$RT),
+                               (ins s34imm:$SI),
+                               "pli $RT, $SI", IIC_IntSimple, []>;
+    }
+  }
+  defm PADDI :
+    MLS_DForm_R_SI34_RTA5_p<14, (outs gprc:$RT), (ins gprc:$RA, s34imm:$SI),
+                            (ins immZero:$RA, s34imm:$SI),
+                            "paddi $RT, $RA, $SI", IIC_LdStLFD>;
+  let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
+    def PLI : MLS_DForm2_r0<14, (outs gprc:$RT),
+                            (ins s34imm:$SI),
+                            "pli $RT, $SI", IIC_IntSimple, []>;
+  }
+}
+
Index: llvm/lib/Target/PowerPC/PPCScheduleP9.td
===================================================================
--- llvm/lib/Target/PowerPC/PPCScheduleP9.td
+++ llvm/lib/Target/PowerPC/PPCScheduleP9.td
@@ -40,9 +40,9 @@
 
   let CompleteModel = 1;
 
-  // Do not support QPX (Quad Processing eXtension) or SPE (Signal Procesing
-  // Engine) on Power 9.
-  let UnsupportedFeatures = [HasQPX, HasSPE];
+  // Do not support QPX (Quad Processing eXtension), SPE (Signal Procesing
+  // Engine) or prefixed instructions on Power 9.
+  let UnsupportedFeatures = [HasQPX, HasSPE, PrefixInstrs];
 
 }
 
Index: llvm/lib/Target/PowerPC/PPCSubtarget.h
===================================================================
--- llvm/lib/Target/PowerPC/PPCSubtarget.h
+++ llvm/lib/Target/PowerPC/PPCSubtarget.h
@@ -105,6 +105,7 @@
   bool HasP8Crypto;
   bool HasP9Vector;
   bool HasP9Altivec;
+  bool HasPrefixInstrs;
   bool HasFCPSGN;
   bool HasFSQRT;
   bool HasFRE, HasFRES, HasFRSQRTE, HasFRSQRTES;
@@ -261,6 +262,7 @@
   bool hasP8Crypto() const { return HasP8Crypto; }
   bool hasP9Vector() const { return HasP9Vector; }
   bool hasP9Altivec() const { return HasP9Altivec; }
+  bool hasPrefixInstrs() const { return HasPrefixInstrs; }
   bool hasMFOCRF() const { return HasMFOCRF; }
   bool hasISEL() const { return HasISEL; }
   bool hasBPERMD() const { return HasBPERMD; }
Index: llvm/lib/Target/PowerPC/PPCSubtarget.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCSubtarget.cpp
+++ llvm/lib/Target/PowerPC/PPCSubtarget.cpp
@@ -78,6 +78,7 @@
   HasP8Crypto = false;
   HasP9Vector = false;
   HasP9Altivec = false;
+  HasPrefixInstrs = false;
   HasFCPSGN = false;
   HasFSQRT = false;
   HasFRE = false;
Index: llvm/test/CodeGen/PowerPC/future-check-features.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/future-check-features.ll
@@ -0,0 +1,19 @@
+; RUN: llc -mattr=prefix-instrs -verify-machineinstrs \
+; RUN:   -mtriple=powerpc64le-unknown-unknown -ppc-asm-full-reg-names \
+; RUN:   %s -o - 2>&1 | FileCheck %s
+; RUN: llc -mattr=prefix-instrs -verify-machineinstrs \
+; RUN:   -mtriple=powerpc64-unknown-unknown -ppc-asm-full-reg-names \
+; RUN:   %s -o - 2>&1 | FileCheck %s
+
+define dso_local signext i32 @f() {
+entry:
+  ret i32 0
+}
+
+; Make sure that all of the features listed are recognized.
+; CHECK-NOT:    is not a recognized feature for this target
+
+; Make sure that the test was actually compiled.
+; CHECK:        li r3, 0
+; CHECK-NEXT:   blr
+
Index: llvm/test/MC/Disassembler/PowerPC/futureinsts.txt
===================================================================
--- /dev/null
+++ llvm/test/MC/Disassembler/PowerPC/futureinsts.txt
@@ -0,0 +1,9 @@
+# RUN: llvm-mc --disassemble %s -triple powerpc64-unknown-linux-gnu \
+# RUN:   -mcpu=future | FileCheck %s
+
+# CHECK: paddi 1, 2, 8589934591, 0
+0x06 0x01 0xff 0xff 0x38 0x22 0xff 0xff
+
+# CHECK: paddi 1, 0, -8589934592, 1
+0x06 0x12 0x00 0x00 0x38 0x20 0x00 0x00
+
Index: llvm/test/MC/PowerPC/future.s
===================================================================
--- /dev/null
+++ llvm/test/MC/PowerPC/future.s
@@ -0,0 +1,27 @@
+# RUN: llvm-mc -triple powerpc64-unknown-linux-gnu --show-encoding %s | \
+# RUN:   FileCheck -check-prefix=CHECK-BE %s
+# RUN: llvm-mc -triple powerpc64le-unknown-linux-gnu --show-encoding %s | \
+# RUN:   FileCheck -check-prefix=CHECK-LE %s
+
+# CHECK-BE: paddi 1, 2, 8589934591, 0             # encoding: [0x06,0x01,0xff,0xff
+# CHECK-BE-SAME:                                               0x38,0x22,0xff,0xff]
+# CHECK-LE: paddi 1, 2, 8589934591, 0             # encoding: [0xff,0xff,0x01,0x06
+# CHECK-LE-SAME:                                               0xff,0xff,0x22,0x38]
+            paddi 1, 2, 8589934591, 0
+# CHECK-BE: paddi 1, 0, -8589934592, 1            # encoding: [0x06,0x12,0x00,0x00
+# CHECK-BE-SAME:                                               0x38,0x20,0x00,0x00]
+# CHECK-LE: paddi 1, 0, -8589934592, 1            # encoding: [0x00,0x00,0x12,0x06
+# CHECK-LE-SAME:                                               0x00,0x00,0x20,0x38]
+            paddi 1, 0, -8589934592, 1
+# CHECK-BE: pli 1, -8589934592                    # encoding: [0x06,0x02,0x00,0x00
+# CHECK-BE-SAME:                                               0x38,0x20,0x00,0x00]
+# CHECK-LE: pli 1, -8589934592                    # encoding: [0x00,0x00,0x02,0x06
+# CHECK-LE-SAME:                                               0x00,0x00,0x20,0x38]
+            pli 1, -8589934592
+# CHECK-BE: pli 1, 8589934591                     # encoding: [0x06,0x01,0xff,0xff
+# CHECK-BE-SAME:                                               0x38,0x20,0xff,0xff]
+# CHECK-LE: pli 1, 8589934591                     # encoding: [0xff,0xff,0x01,0x06
+# CHECK-LE-SAME:                                               0xff,0xff,0x20,0x38]
+            pli 1, 8589934591
+
+