mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
[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
This commit is contained in:
parent
03f2c49843
commit
c2d91820e1
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -59,6 +59,12 @@ public:
|
||||
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;
|
||||
|
@ -214,6 +214,10 @@ def FeaturePrefixInstrs : SubtargetFeature<"prefix-instrs", "HasPrefixInstrs",
|
||||
"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
|
||||
@ -303,7 +307,8 @@ def ProcessorFeatures {
|
||||
// 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 =
|
||||
|
@ -803,6 +803,30 @@ def PPCRegGxRCNoR0Operand : AsmOperandClass {
|
||||
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";
|
||||
|
@ -95,6 +95,34 @@ multiclass MLS_DForm_R_SI34_RTA5_p<bits<6> opcode, dag OOL, dag IOL,
|
||||
!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()">;
|
||||
|
||||
@ -119,5 +147,19 @@ let Predicates = [PrefixInstrs] in {
|
||||
(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>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,6 +79,7 @@ void PPCSubtarget::initializeEnvironment() {
|
||||
HasP9Vector = false;
|
||||
HasP9Altivec = false;
|
||||
HasPrefixInstrs = false;
|
||||
HasPCRelativeMemops = false;
|
||||
HasFCPSGN = false;
|
||||
HasFSQRT = false;
|
||||
HasFRE = false;
|
||||
|
@ -106,6 +106,7 @@ protected:
|
||||
bool HasP9Vector;
|
||||
bool HasP9Altivec;
|
||||
bool HasPrefixInstrs;
|
||||
bool HasPCRelativeMemops;
|
||||
bool HasFCPSGN;
|
||||
bool HasFSQRT;
|
||||
bool HasFRE, HasFRES, HasFRSQRTE, HasFRSQRTES;
|
||||
@ -257,6 +258,7 @@ public:
|
||||
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; }
|
||||
|
@ -1,7 +1,7 @@
|
||||
; 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
|
||||
|
||||
|
@ -1,5 +1,10 @@
|
||||
# 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
|
||||
|
@ -7,3 +7,9 @@
|
||||
# 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
|
||||
|
||||
|
11
test/MC/PowerPC/future-errors.s
Normal file
11
test/MC/PowerPC/future-errors.s
Normal file
@ -0,0 +1,11 @@
|
||||
# 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
|
||||
|
@ -23,5 +23,14 @@
|
||||
# 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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user