Skip to content

Commit 4b414d9

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
1 parent 78dc649 commit 4b414d9

File tree

16 files changed

+197
-5
lines changed

16 files changed

+197
-5
lines changed

llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,9 @@ struct PPCOperand : public MCParsedAsmOperand {
356356
bool isS16ImmX16() const { return Kind == Expression ||
357357
(Kind == Immediate && isInt<16>(getImm()) &&
358358
(getImm() & 15) == 0); }
359+
bool isS34ImmX16() const { return Kind == Expression ||
360+
(Kind == Immediate && isInt<34>(getImm()) &&
361+
(getImm() & 15) == 0); }
359362
bool isS34Imm() const {
360363
// Once the PC-Rel ABI is finalized, evaluate whether a 34-bit
361364
// ContextImmediate is needed.

llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,35 @@ static DecodeStatus decodeMemRIX16Operands(MCInst &Inst, uint64_t Imm,
270270
return MCDisassembler::Success;
271271
}
272272

273+
static DecodeStatus decodeMemRI34PCRelOperands(MCInst &Inst, uint64_t Imm,
274+
int64_t Address,
275+
const void *Decoder) {
276+
// Decode the memri34_pcrel field (imm, reg), which has the low 34-bits as the
277+
// displacement, and the next 5 bits as an immediate 0.
278+
uint64_t Base = Imm >> 34;
279+
uint64_t Disp = Imm & 0x3FFFFFFFFUL;
280+
281+
assert(Base < 32 && "Invalid base register");
282+
283+
Inst.addOperand(MCOperand::createImm(SignExtend64<34>(Disp)));
284+
return decodeImmZeroOperand(Inst, Base, Address, Decoder);
285+
}
286+
287+
static DecodeStatus decodeMemRI34Operands(MCInst &Inst, uint64_t Imm,
288+
int64_t Address,
289+
const void *Decoder) {
290+
// Decode the memri34 field (imm, reg), which has the low 34-bits as the
291+
// displacement, and the next 5 bits as the register #.
292+
uint64_t Base = Imm >> 34;
293+
uint64_t Disp = Imm & 0x3FFFFFFFFUL;
294+
295+
assert(Base < 32 && "Invalid base register");
296+
297+
Inst.addOperand(MCOperand::createImm(SignExtend64<34>(Disp)));
298+
Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
299+
return MCDisassembler::Success;
300+
}
301+
273302
static DecodeStatus decodeSPE8Operands(MCInst &Inst, uint64_t Imm,
274303
int64_t Address, const void *Decoder) {
275304
// Decode the spe8disp field (imm, reg), which has the low 5-bits as the

llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,22 @@ void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
465465
O << ')';
466466
}
467467

468+
void PPCInstPrinter::printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo,
469+
raw_ostream &O) {
470+
printS34ImmOperand(MI, OpNo, O);
471+
O << '(';
472+
printImmZeroOperand(MI, OpNo+1, O);
473+
O << ')';
474+
}
475+
476+
void PPCInstPrinter::printMemRegImm34(const MCInst *MI, unsigned OpNo,
477+
raw_ostream &O) {
478+
printS34ImmOperand(MI, OpNo, O);
479+
O << '(';
480+
printOperand(MI, OpNo+1, O);
481+
O << ')';
482+
}
483+
468484
void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
469485
raw_ostream &O) {
470486
// When used as the base register, r0 reads constant zero rather than

llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ class PPCInstPrinter : public MCInstPrinter {
7171
void printcrbitm(const MCInst *MI, unsigned OpNo, raw_ostream &O);
7272

7373
void printMemRegImm(const MCInst *MI, unsigned OpNo, raw_ostream &O);
74+
void printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo, raw_ostream &O);
75+
void printMemRegImm34(const MCInst *MI, unsigned OpNo, raw_ostream &O);
7476
void printMemRegReg(const MCInst *MI, unsigned OpNo, raw_ostream &O);
7577
};
7678
} // end namespace llvm

llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,37 @@ unsigned PPCMCCodeEmitter::getMemRIX16Encoding(const MCInst &MI, unsigned OpNo,
159159
return RegBits;
160160
}
161161

162+
uint64_t
163+
PPCMCCodeEmitter::getMemRI34PCRelEncoding(const MCInst &MI, unsigned OpNo,
164+
SmallVectorImpl<MCFixup> &Fixups,
165+
const MCSubtargetInfo &STI) const {
166+
// Encode (imm, reg) as a memri34, which has the low 34-bits as the
167+
// displacement and the next 5 bits as an immediate 0.
168+
assert(MI.getOperand(OpNo + 1).isImm() && "Expecting an immediate.");
169+
uint64_t RegBits =
170+
getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI) << 34;
171+
172+
if (RegBits != 0)
173+
report_fatal_error("Operand must be 0");
174+
175+
const MCOperand &MO = MI.getOperand(OpNo);
176+
return ((getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL) | RegBits;
177+
}
178+
179+
uint64_t
180+
PPCMCCodeEmitter::getMemRI34Encoding(const MCInst &MI, unsigned OpNo,
181+
SmallVectorImpl<MCFixup> &Fixups,
182+
const MCSubtargetInfo &STI) const {
183+
// Encode (imm, reg) as a memri34, which has the low 34-bits as the
184+
// displacement and the next 5 bits as the register #.
185+
assert(MI.getOperand(OpNo + 1).isReg() && "Expecting a register.");
186+
uint64_t RegBits =
187+
getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI) << 34;
188+
189+
const MCOperand &MO = MI.getOperand(OpNo);
190+
return ((getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL) | RegBits;
191+
}
192+
162193
unsigned PPCMCCodeEmitter::getSPE8DisEncoding(const MCInst &MI, unsigned OpNo,
163194
SmallVectorImpl<MCFixup> &Fixups,
164195
const MCSubtargetInfo &STI)

llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ class PPCMCCodeEmitter : public MCCodeEmitter {
5959
unsigned getMemRIX16Encoding(const MCInst &MI, unsigned OpNo,
6060
SmallVectorImpl<MCFixup> &Fixups,
6161
const MCSubtargetInfo &STI) const;
62+
uint64_t getMemRI34PCRelEncoding(const MCInst &MI, unsigned OpNo,
63+
SmallVectorImpl<MCFixup> &Fixups,
64+
const MCSubtargetInfo &STI) const;
65+
uint64_t getMemRI34Encoding(const MCInst &MI, unsigned OpNo,
66+
SmallVectorImpl<MCFixup> &Fixups,
67+
const MCSubtargetInfo &STI) const;
6268
unsigned getSPE8DisEncoding(const MCInst &MI, unsigned OpNo,
6369
SmallVectorImpl<MCFixup> &Fixups,
6470
const MCSubtargetInfo &STI) const;

llvm/lib/Target/PowerPC/PPC.td

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@ def FeaturePrefixInstrs : SubtargetFeature<"prefix-instrs", "HasPrefixInstrs",
214214
"Enable prefixed instructions",
215215
[FeatureISA3_0, FeatureP8Vector,
216216
FeatureP9Altivec]>;
217+
def FeaturePCRelativeMemops :
218+
SubtargetFeature<"pcrelative-memops", "HasPCRelativeMemops", "true",
219+
"Enable PC relative Memory Ops",
220+
[FeatureISA3_0]>;
217221

218222
// Since new processors generally contain a superset of features of those that
219223
// came before them, the idea is to make implementations of new processors
@@ -303,7 +307,8 @@ def ProcessorFeatures {
303307
// For future CPU we assume that all of the existing features from Power 9
304308
// still exist with the exception of those we know are Power 9 specific.
305309
list<SubtargetFeature> FutureAdditionalFeatures = [];
306-
list<SubtargetFeature> FutureSpecificFeatures = [FeaturePrefixInstrs];
310+
list<SubtargetFeature> FutureSpecificFeatures =
311+
[FeaturePrefixInstrs, FeaturePCRelativeMemops];
307312
list<SubtargetFeature> FutureInheritableFeatures =
308313
!listconcat(P9InheritableFeatures, FutureAdditionalFeatures);
309314
list<SubtargetFeature> FutureFeatures =

llvm/lib/Target/PowerPC/PPCInstrInfo.td

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,30 @@ def PPCRegGxRCNoR0Operand : AsmOperandClass {
803803
def ptr_rc_nor0 : Operand<iPTR>, PointerLikeRegClass<1> {
804804
let ParserMatchClass = PPCRegGxRCNoR0Operand;
805805
}
806+
807+
// New addressing modes with 34 bit immediates.
808+
def PPCDispRI34Operand : AsmOperandClass {
809+
let Name = "DispRI34"; let PredicateMethod = "isS34Imm";
810+
let RenderMethod = "addImmOperands";
811+
}
812+
def dispRI34 : Operand<iPTR> {
813+
let ParserMatchClass = PPCDispRI34Operand;
814+
}
815+
def memri34 : Operand<iPTR> { // memri, imm is a 34-bit value.
816+
let PrintMethod = "printMemRegImm34";
817+
let MIOperandInfo = (ops dispRI34:$imm, ptr_rc_nor0:$reg);
818+
let EncoderMethod = "getMemRI34Encoding";
819+
let DecoderMethod = "decodeMemRI34Operands";
820+
}
821+
// memri, imm is a 34-bit value for pc-relative instructions where
822+
// base register is set to zero.
823+
def memri34_pcrel : Operand<iPTR> { // memri, imm is a 34-bit value.
824+
let PrintMethod = "printMemRegImm34PCRel";
825+
let MIOperandInfo = (ops dispRI34:$imm, immZero:$reg);
826+
let EncoderMethod = "getMemRI34PCRelEncoding";
827+
let DecoderMethod = "decodeMemRI34PCRelOperands";
828+
}
829+
806830
// A version of ptr_rc usable with the asm parser.
807831
def PPCRegGxRCOperand : AsmOperandClass {
808832
let Name = "RegGxRC"; let PredicateMethod = "isRegNumber";

llvm/lib/Target/PowerPC/PPCInstrPrefix.td

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,34 @@ multiclass MLS_DForm_R_SI34_RTA5_p<bits<6> opcode, dag OOL, dag IOL,
9595
!strconcat(asmstr, ", 1"), itin, []>, isPCRel;
9696
}
9797

98+
class 8LS_DForm_R_D34_RTA5<bits<6> opcode, dag OOL, dag IOL, string asmstr,
99+
InstrItinClass itin, list<dag> pattern>
100+
: PI<1, opcode, OOL, IOL, asmstr, itin> {
101+
bits<5> RT;
102+
bits<39> D_RA;
103+
104+
let Pattern = pattern;
105+
106+
// The prefix.
107+
let Inst{6-10} = 0;
108+
let Inst{11} = PCRel;
109+
let Inst{12-13} = 0;
110+
let Inst{14-31} = D_RA{33-16}; // d0
111+
112+
// The instruction.
113+
let Inst{38-42} = RT{4-0};
114+
let Inst{43-47} = D_RA{38-34}; // RA
115+
let Inst{48-63} = D_RA{15-0}; // d1
116+
}
117+
118+
multiclass 8LS_DForm_R_D34_RTA5_p<bits<6> opcode, dag OOL, dag IOL,
119+
dag PCRel_IOL, string asmstr,
120+
InstrItinClass itin> {
121+
def NAME : 8LS_DForm_R_D34_RTA5<opcode, OOL, IOL,
122+
!strconcat(asmstr, ", 0"), itin, []>;
123+
def pc : 8LS_DForm_R_D34_RTA5<opcode, OOL, PCRel_IOL,
124+
!strconcat(asmstr, ", 1"), itin, []>, isPCRel;
125+
}
98126

99127
def PrefixInstrs : Predicate<"PPCSubTarget->hasPrefixInstrs()">;
100128

@@ -119,5 +147,19 @@ let Predicates = [PrefixInstrs] in {
119147
(ins s34imm:$SI),
120148
"pli $RT, $SI", IIC_IntSimple, []>;
121149
}
150+
151+
let mayLoad = 1, mayStore = 0 in {
152+
defm PLD :
153+
8LS_DForm_R_D34_RTA5_p<57, (outs g8rc:$RT), (ins memri34:$D_RA),
154+
(ins memri34_pcrel:$D_RA), "pld $RT, $D_RA",
155+
IIC_LdStLFD>;
156+
}
157+
158+
let mayStore = 1, mayLoad = 0 in {
159+
defm PSTD :
160+
8LS_DForm_R_D34_RTA5_p<61, (outs), (ins g8rc:$RS, memri34:$D_RA),
161+
(ins g8rc:$RS, memri34_pcrel:$D_RA),
162+
"pstd $RS, $D_RA", IIC_LdStLFD>;
163+
}
122164
}
123165

llvm/lib/Target/PowerPC/PPCSubtarget.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ void PPCSubtarget::initializeEnvironment() {
7979
HasP9Vector = false;
8080
HasP9Altivec = false;
8181
HasPrefixInstrs = false;
82+
HasPCRelativeMemops = false;
8283
HasFCPSGN = false;
8384
HasFSQRT = false;
8485
HasFRE = false;

llvm/lib/Target/PowerPC/PPCSubtarget.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class PPCSubtarget : public PPCGenSubtargetInfo {
106106
bool HasP9Vector;
107107
bool HasP9Altivec;
108108
bool HasPrefixInstrs;
109+
bool HasPCRelativeMemops;
109110
bool HasFCPSGN;
110111
bool HasFSQRT;
111112
bool HasFRE, HasFRES, HasFRSQRTE, HasFRSQRTES;
@@ -257,6 +258,7 @@ class PPCSubtarget : public PPCGenSubtargetInfo {
257258
bool hasP9Vector() const { return HasP9Vector; }
258259
bool hasP9Altivec() const { return HasP9Altivec; }
259260
bool hasPrefixInstrs() const { return HasPrefixInstrs; }
261+
bool hasPCRelativeMemops() const { return HasPCRelativeMemops; }
260262
bool hasMFOCRF() const { return HasMFOCRF; }
261263
bool hasISEL() const { return HasISEL; }
262264
bool hasBPERMD() const { return HasBPERMD; }

llvm/test/CodeGen/PowerPC/future-check-features.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
; RUN: llc -mattr=prefix-instrs -verify-machineinstrs \
1+
; RUN: llc -mattr=pcrelative-memops,prefix-instrs -verify-machineinstrs \
22
; RUN: -mtriple=powerpc64le-unknown-unknown -ppc-asm-full-reg-names \
33
; RUN: %s -o - 2>&1 | FileCheck %s
4-
; RUN: llc -mattr=prefix-instrs -verify-machineinstrs \
4+
; RUN: llc -mattr=pcrelative-memops,prefix-instrs -verify-machineinstrs \
55
; RUN: -mtriple=powerpc64-unknown-unknown -ppc-asm-full-reg-names \
66
; RUN: %s -o - 2>&1 | FileCheck %s
77

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
# RUN: llvm-mc --disassemble %s -mcpu=future -triple powerpc64-unknown-linux-gnu < %s 2>&1 | FileCheck %s
1+
# RUN: llvm-mc --disassemble %s -mcpu=future -triple \
2+
# RUN: powerpc64-unknown-linux-gnu < %s 2>&1 | FileCheck %s
23

34
# paddi 1, 2, 8589934591, 1. However, RA is not zero with R=1
45
# CHECK: warning: invalid instruction encoding
56
0x06 0x11 0xff 0xff 0x38 0x22 0xff 0xff
7+
8+
# pld 1, -8589934592(3), 1. However, RA is not zero with R=1
9+
# CHECK: warning: invalid instruction encoding
10+
0x04 0x12 0x00 0x00 0xe0 0x23 0x00 0x00

llvm/test/MC/Disassembler/PowerPC/futureinsts.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@
77
# CHECK: paddi 1, 0, -8589934592, 1
88
0x06 0x12 0x00 0x00 0x38 0x20 0x00 0x00
99

10+
# CHECK: pld 1, -8589934592(3), 0
11+
0x04 0x02 0x00 0x00 0xe4 0x23 0x00 0x00
12+
13+
# CHECK: pld 1, 8589934591(0), 1
14+
0x04 0x11 0xff 0xff 0xe4 0x20 0xff 0xff
15+

llvm/test/MC/PowerPC/future-errors.s

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# RUN: not llvm-mc -triple powerpc64-unknown-unknown < %s 2> %t
2+
# RUN: FileCheck < %t %s
3+
# RUN: not llvm-mc -triple powerpc64le-unknown-unknown < %s 2> %t
4+
# RUN: FileCheck < %t %s
5+
6+
# CHECK: error: invalid operand for instruction
7+
paddi 1, 1, 32, 1
8+
9+
# CHECK: error: invalid operand for instruction
10+
pld 1, 32(1), 1
11+

llvm/test/MC/PowerPC/future.s

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,14 @@
2323
# CHECK-LE: pli 1, 8589934591 # encoding: [0xff,0xff,0x01,0x06
2424
# CHECK-LE-SAME: 0xff,0xff,0x20,0x38]
2525
pli 1, 8589934591
26-
26+
# CHECK-BE: pld 1, -8589934592(3), 0 # encoding: [0x04,0x02,0x00,0x00,
27+
# CHECK-BE-SAME: 0xe4,0x23,0x00,0x00]
28+
# CHECK-LE: pld 1, -8589934592(3), 0 # encoding: [0x00,0x00,0x02,0x04
29+
# CHECK-LE-SAME: 0x00,0x00,0x23,0xe4]
30+
pld 1, -8589934592(3), 0
31+
# CHECK-BE: pld 1, 8589934591(0), 1 # encoding: [0x04,0x11,0xff,0xff
32+
# CHECK-BE-SAME: 0xe4,0x20,0xff,0xff]
33+
# CHECK-LE: pld 1, 8589934591(0), 1 # encoding: [0xff,0xff,0x11,0x04,
34+
# CHECK-LE-SAME: 0xff,0xff,0x20,0xe4]
35+
pld 1, 8589934591(0), 1
2736

0 commit comments

Comments
 (0)