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.
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
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
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
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)
unsigned getMemRIX16Encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+ uint64_t getMemRI34PCRelEncoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+ uint64_t getMemRI34Encoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
unsigned getSPE8DisEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
"Enable prefixed instructions",
[FeatureISA3_0, FeatureP8Vector,
FeatureP9Altivec]>;
+def FeaturePCRelativeMemops :
+ SubtargetFeature<"pcrelative-memops", "HasPCRelativeMemops", "true",
+ "Enable PC relative Memory Ops",
+ [FeatureISA3_0]>;
// Since new processors generally contain a superset of features of those that
// came before them, the idea is to make implementations of new processors
// 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 = [FeaturePrefixInstrs];
+ list<SubtargetFeature> FutureSpecificFeatures =
+ [FeaturePrefixInstrs, FeaturePCRelativeMemops];
list<SubtargetFeature> FutureInheritableFeatures =
!listconcat(P9InheritableFeatures, FutureAdditionalFeatures);
list<SubtargetFeature> FutureFeatures =
def ptr_rc_nor0 : Operand<iPTR>, PointerLikeRegClass<1> {
let ParserMatchClass = PPCRegGxRCNoR0Operand;
}
+
+// New addressing modes with 34 bit immediates.
+def PPCDispRI34Operand : AsmOperandClass {
+ let Name = "DispRI34"; let PredicateMethod = "isS34Imm";
+ let RenderMethod = "addImmOperands";
+}
+def dispRI34 : Operand<iPTR> {
+ let ParserMatchClass = PPCDispRI34Operand;
+}
+def memri34 : Operand<iPTR> { // memri, imm is a 34-bit value.
+ let PrintMethod = "printMemRegImm34";
+ let MIOperandInfo = (ops dispRI34:$imm, ptr_rc_nor0:$reg);
+ let EncoderMethod = "getMemRI34Encoding";
+ let DecoderMethod = "decodeMemRI34Operands";
+}
+// memri, imm is a 34-bit value for pc-relative instructions where
+// base register is set to zero.
+def memri34_pcrel : Operand<iPTR> { // memri, imm is a 34-bit value.
+ let PrintMethod = "printMemRegImm34PCRel";
+ let MIOperandInfo = (ops dispRI34:$imm, immZero:$reg);
+ let EncoderMethod = "getMemRI34PCRelEncoding";
+ let DecoderMethod = "decodeMemRI34PCRelOperands";
+}
+
// A version of ptr_rc usable with the asm parser.
def PPCRegGxRCOperand : AsmOperandClass {
let Name = "RegGxRC"; let PredicateMethod = "isRegNumber";
!strconcat(asmstr, ", 1"), itin, []>, isPCRel;
}
+class 8LS_DForm_R_D34_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<39> D_RA;
+
+ let Pattern = pattern;
+
+ // The prefix.
+ let Inst{6-10} = 0;
+ let Inst{11} = PCRel;
+ let Inst{12-13} = 0;
+ let Inst{14-31} = D_RA{33-16}; // d0
+
+ // The instruction.
+ let Inst{38-42} = RT{4-0};
+ let Inst{43-47} = D_RA{38-34}; // RA
+ let Inst{48-63} = D_RA{15-0}; // d1
+}
+
+multiclass 8LS_DForm_R_D34_RTA5_p<bits<6> opcode, dag OOL, dag IOL,
+ dag PCRel_IOL, string asmstr,
+ InstrItinClass itin> {
+ def NAME : 8LS_DForm_R_D34_RTA5<opcode, OOL, IOL,
+ !strconcat(asmstr, ", 0"), itin, []>;
+ def pc : 8LS_DForm_R_D34_RTA5<opcode, OOL, PCRel_IOL,
+ !strconcat(asmstr, ", 1"), itin, []>, isPCRel;
+}
def PrefixInstrs : Predicate<"PPCSubTarget->hasPrefixInstrs()">;
(ins s34imm:$SI),
"pli $RT, $SI", IIC_IntSimple, []>;
}
+
+ let mayLoad = 1, mayStore = 0 in {
+ defm PLD :
+ 8LS_DForm_R_D34_RTA5_p<57, (outs g8rc:$RT), (ins memri34:$D_RA),
+ (ins memri34_pcrel:$D_RA), "pld $RT, $D_RA",
+ IIC_LdStLFD>;
+ }
+
+ let mayStore = 1, mayLoad = 0 in {
+ defm PSTD :
+ 8LS_DForm_R_D34_RTA5_p<61, (outs), (ins g8rc:$RS, memri34:$D_RA),
+ (ins g8rc:$RS, memri34_pcrel:$D_RA),
+ "pstd $RS, $D_RA", IIC_LdStLFD>;
+ }
}
HasP9Vector = false;
HasP9Altivec = false;
HasPrefixInstrs = false;
+ HasPCRelativeMemops = false;
HasFCPSGN = false;
HasFSQRT = false;
HasFRE = false;
bool HasP9Vector;
bool HasP9Altivec;
bool HasPrefixInstrs;
+ bool HasPCRelativeMemops;
bool HasFCPSGN;
bool HasFSQRT;
bool HasFRE, HasFRES, HasFRSQRTE, HasFRSQRTES;
bool hasP9Vector() const { return HasP9Vector; }
bool hasP9Altivec() const { return HasP9Altivec; }
bool hasPrefixInstrs() const { return HasPrefixInstrs; }
+ bool hasPCRelativeMemops() const { return HasPCRelativeMemops; }
bool hasMFOCRF() const { return HasMFOCRF; }
bool hasISEL() const { return HasISEL; }
bool hasBPERMD() const { return HasBPERMD; }
-; RUN: llc -mattr=prefix-instrs -verify-machineinstrs \
+; RUN: llc -mattr=pcrelative-memops,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: llc -mattr=pcrelative-memops,prefix-instrs -verify-machineinstrs \
; RUN: -mtriple=powerpc64-unknown-unknown -ppc-asm-full-reg-names \
; RUN: %s -o - 2>&1 | FileCheck %s
-# RUN: llvm-mc --disassemble %s -mcpu=future -triple powerpc64-unknown-linux-gnu < %s 2>&1 | FileCheck %s
+# RUN: llvm-mc --disassemble %s -mcpu=future -triple \
+# RUN: powerpc64-unknown-linux-gnu < %s 2>&1 | FileCheck %s
# paddi 1, 2, 8589934591, 1. However, RA is not zero with R=1
# CHECK: warning: invalid instruction encoding
0x06 0x11 0xff 0xff 0x38 0x22 0xff 0xff
+
+# pld 1, -8589934592(3), 1. However, RA is not zero with R=1
+# CHECK: warning: invalid instruction encoding
+0x04 0x12 0x00 0x00 0xe0 0x23 0x00 0x00
# CHECK: paddi 1, 0, -8589934592, 1
0x06 0x12 0x00 0x00 0x38 0x20 0x00 0x00
+# CHECK: pld 1, -8589934592(3), 0
+0x04 0x02 0x00 0x00 0xe4 0x23 0x00 0x00
+
+# CHECK: pld 1, 8589934591(0), 1
+0x04 0x11 0xff 0xff 0xe4 0x20 0xff 0xff
+
--- /dev/null
+# RUN: not llvm-mc -triple powerpc64-unknown-unknown < %s 2> %t
+# RUN: FileCheck < %t %s
+# RUN: not llvm-mc -triple powerpc64le-unknown-unknown < %s 2> %t
+# RUN: FileCheck < %t %s
+
+ # CHECK: error: invalid operand for instruction
+paddi 1, 1, 32, 1
+
+# CHECK: error: invalid operand for instruction
+pld 1, 32(1), 1
+
# CHECK-LE: pli 1, 8589934591 # encoding: [0xff,0xff,0x01,0x06
# CHECK-LE-SAME: 0xff,0xff,0x20,0x38]
pli 1, 8589934591
-
+# CHECK-BE: pld 1, -8589934592(3), 0 # encoding: [0x04,0x02,0x00,0x00,
+# CHECK-BE-SAME: 0xe4,0x23,0x00,0x00]
+# CHECK-LE: pld 1, -8589934592(3), 0 # encoding: [0x00,0x00,0x02,0x04
+# CHECK-LE-SAME: 0x00,0x00,0x23,0xe4]
+ pld 1, -8589934592(3), 0
+# CHECK-BE: pld 1, 8589934591(0), 1 # encoding: [0x04,0x11,0xff,0xff
+# CHECK-BE-SAME: 0xe4,0x20,0xff,0xff]
+# CHECK-LE: pld 1, 8589934591(0), 1 # encoding: [0xff,0xff,0x11,0x04,
+# CHECK-LE-SAME: 0xff,0xff,0x20,0xe4]
+ pld 1, 8589934591(0), 1