Commit 4b414d9a authored by Victor Huang's avatar Victor Huang
Browse files

[PowerPC][Future] Add pld and pstd to future CPU

Add the prefixed instructions pld and pstd to future CPU. These are load and
store instructions that require new operand types that are 34 bits. This patch
adds the two instructions as well as the operand types required.

Note that this patch also makes a minor change to tablegen to account for the
fact that some instructions are going to require shifts greater than 31 bits
for the new 34 bit instructions.

Differential Revision: https://reviews.llvm.org/D72574
parent 78dc6498
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -356,6 +356,9 @@ public:
  bool isS16ImmX16() const { return Kind == Expression ||
                                    (Kind == Immediate && isInt<16>(getImm()) &&
                                     (getImm() & 15) == 0); }
  bool isS34ImmX16() const { return Kind == Expression ||
                                    (Kind == Immediate && isInt<34>(getImm()) &&
                                    (getImm() & 15) == 0); }
  bool isS34Imm() const {
    // Once the PC-Rel ABI is finalized, evaluate whether a 34-bit
    // ContextImmediate is needed.
+29 −0
Original line number Diff line number Diff line
@@ -270,6 +270,35 @@ static DecodeStatus decodeMemRIX16Operands(MCInst &Inst, uint64_t Imm,
  return MCDisassembler::Success;
}

static DecodeStatus decodeMemRI34PCRelOperands(MCInst &Inst, uint64_t Imm,
                                               int64_t Address,
                                               const void *Decoder) {
  // Decode the memri34_pcrel field (imm, reg), which has the low 34-bits as the
  // displacement, and the next 5 bits as an immediate 0.
  uint64_t Base = Imm >> 34;
  uint64_t Disp = Imm & 0x3FFFFFFFFUL;

  assert(Base < 32 && "Invalid base register");

  Inst.addOperand(MCOperand::createImm(SignExtend64<34>(Disp)));
  return decodeImmZeroOperand(Inst, Base, Address, Decoder);
}

static DecodeStatus decodeMemRI34Operands(MCInst &Inst, uint64_t Imm,
                                          int64_t Address,
                                          const void *Decoder) {
  // Decode the memri34 field (imm, reg), which has the low 34-bits as the
  // displacement, and the next 5 bits as the register #.
  uint64_t Base = Imm >> 34;
  uint64_t Disp = Imm & 0x3FFFFFFFFUL;

  assert(Base < 32 && "Invalid base register");

  Inst.addOperand(MCOperand::createImm(SignExtend64<34>(Disp)));
  Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
  return MCDisassembler::Success;
}

static DecodeStatus decodeSPE8Operands(MCInst &Inst, uint64_t Imm,
                                         int64_t Address, const void *Decoder) {
  // Decode the spe8disp field (imm, reg), which has the low 5-bits as the
+16 −0
Original line number Diff line number Diff line
@@ -465,6 +465,22 @@ void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
  O << ')';
}

void PPCInstPrinter::printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo,
                                           raw_ostream &O) {
  printS34ImmOperand(MI, OpNo, O);
  O << '(';
  printImmZeroOperand(MI, OpNo+1, O);
  O << ')';
}

void PPCInstPrinter::printMemRegImm34(const MCInst *MI, unsigned OpNo,
                                        raw_ostream &O) {
  printS34ImmOperand(MI, OpNo, O);
  O << '(';
  printOperand(MI, OpNo+1, O);
  O << ')';
}

void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
                                    raw_ostream &O) {
  // When used as the base register, r0 reads constant zero rather than
+2 −0
Original line number Diff line number Diff line
@@ -71,6 +71,8 @@ public:
  void printcrbitm(const MCInst *MI, unsigned OpNo, raw_ostream &O);

  void printMemRegImm(const MCInst *MI, unsigned OpNo, raw_ostream &O);
  void printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo, raw_ostream &O);
  void printMemRegImm34(const MCInst *MI, unsigned OpNo, raw_ostream &O);
  void printMemRegReg(const MCInst *MI, unsigned OpNo, raw_ostream &O);
};
} // end namespace llvm
+31 −0
Original line number Diff line number Diff line
@@ -159,6 +159,37 @@ unsigned PPCMCCodeEmitter::getMemRIX16Encoding(const MCInst &MI, unsigned OpNo,
  return RegBits;
}

uint64_t
PPCMCCodeEmitter::getMemRI34PCRelEncoding(const MCInst &MI, unsigned OpNo,
                                          SmallVectorImpl<MCFixup> &Fixups,
                                          const MCSubtargetInfo &STI) const {
  // Encode (imm, reg) as a memri34, which has the low 34-bits as the
  // displacement and the next 5 bits as an immediate 0.
  assert(MI.getOperand(OpNo + 1).isImm() && "Expecting an immediate.");
  uint64_t RegBits =
    getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI) << 34;

  if (RegBits != 0)
    report_fatal_error("Operand must be 0");

  const MCOperand &MO = MI.getOperand(OpNo);
  return ((getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL) | RegBits;
}

uint64_t
PPCMCCodeEmitter::getMemRI34Encoding(const MCInst &MI, unsigned OpNo,
                                     SmallVectorImpl<MCFixup> &Fixups,
                                     const MCSubtargetInfo &STI) const {
  // Encode (imm, reg) as a memri34, which has the low 34-bits as the
  // displacement and the next 5 bits as the register #.
  assert(MI.getOperand(OpNo + 1).isReg() && "Expecting a register.");
  uint64_t RegBits =
    getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI) << 34;

  const MCOperand &MO = MI.getOperand(OpNo);
  return ((getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL) | RegBits;
}

unsigned PPCMCCodeEmitter::getSPE8DisEncoding(const MCInst &MI, unsigned OpNo,
                                              SmallVectorImpl<MCFixup> &Fixups,
                                              const MCSubtargetInfo &STI)
Loading