mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[PowerPC] Add vector pair load/store instructions and vector pair register class
This patch adds support for the lxvp, lxvpx, plxvp, stxvp, stxvpx and pstxvp instructions in the PowerPC backend. These instructions allow loading and storing VSX register pairs. This patch also adds the VSRp register class definition needed for these instructions. Differential Revision: https://reviews.llvm.org/D84359
This commit is contained in:
parent
33cc850aa4
commit
85360aaf7b
@ -290,6 +290,11 @@ public:
|
||||
return (unsigned) Imm.Val;
|
||||
}
|
||||
|
||||
unsigned getVSRpEvenReg() const {
|
||||
assert(isVSRpEvenRegNumber() && "Invalid access!");
|
||||
return (unsigned) Imm.Val >> 1;
|
||||
}
|
||||
|
||||
unsigned getCCReg() const {
|
||||
assert(isCCRegNumber() && "Invalid access!");
|
||||
return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
|
||||
@ -402,6 +407,9 @@ public:
|
||||
(getImm() & 3) == 0); }
|
||||
bool isImmZero() const { return Kind == Immediate && getImm() == 0; }
|
||||
bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }
|
||||
bool isVSRpEvenRegNumber() const {
|
||||
return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);
|
||||
}
|
||||
bool isVSRegNumber() const {
|
||||
return Kind == Immediate && isUInt<6>(getImm());
|
||||
}
|
||||
@ -502,6 +510,11 @@ public:
|
||||
Inst.addOperand(MCOperand::createReg(SPERegs[getReg()]));
|
||||
}
|
||||
|
||||
void addRegVSRpRCOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
|
||||
}
|
||||
|
||||
void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
Inst.addOperand(MCOperand::createReg(CRBITRegs[getCRBit()]));
|
||||
|
@ -173,6 +173,12 @@ static DecodeStatus DecodeSPERCRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
return decodeRegisterClass(Inst, RegNo, SPERegs);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeVSRpRCRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, VSRpRegs);
|
||||
}
|
||||
|
||||
#define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
|
||||
#define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
|
||||
|
||||
|
@ -156,6 +156,7 @@ using llvm::MCPhysReg;
|
||||
static const MCPhysReg RRegs[32] = PPC_REGS0_31(PPC::R); \
|
||||
static const MCPhysReg XRegs[32] = PPC_REGS0_31(PPC::X); \
|
||||
static const MCPhysReg FRegs[32] = PPC_REGS0_31(PPC::F); \
|
||||
static const MCPhysReg VSRpRegs[32] = PPC_REGS0_31(PPC::VSRp); \
|
||||
static const MCPhysReg SPERegs[32] = PPC_REGS0_31(PPC::S); \
|
||||
static const MCPhysReg VFRegs[32] = PPC_REGS0_31(PPC::VF); \
|
||||
static const MCPhysReg VRegs[32] = PPC_REGS0_31(PPC::V); \
|
||||
|
@ -517,10 +517,79 @@ multiclass 8LS_DForm_R_SI34_XT6_RA5_p<bits<5> opcode, dag OOL, dag IOL,
|
||||
isPCRel;
|
||||
}
|
||||
|
||||
def PPCRegVSRpRCAsmOperand : AsmOperandClass {
|
||||
let Name = "RegVSRpRC"; let PredicateMethod = "isVSRpEvenRegNumber";
|
||||
}
|
||||
|
||||
def vsrprc : RegisterOperand<VSRpRC> {
|
||||
let ParserMatchClass = PPCRegVSRpRCAsmOperand;
|
||||
}
|
||||
|
||||
class DQForm_XTp5_RA17_MEM<bits<6> opcode, bits<4> xo, dag OOL, dag IOL,
|
||||
string asmstr, InstrItinClass itin, list<dag> pattern>
|
||||
: I<opcode, OOL, IOL, asmstr, itin> {
|
||||
bits<5> XTp;
|
||||
bits<17> DQ_RA;
|
||||
let Pattern = pattern;
|
||||
|
||||
let Inst{6-9} = XTp{3-0};
|
||||
let Inst{10} = XTp{4};
|
||||
let Inst{11-15} = DQ_RA{16-12}; // Register #
|
||||
let Inst{16-27} = DQ_RA{11-0}; // Displacement.
|
||||
let Inst{28-31} = xo;
|
||||
}
|
||||
|
||||
class XForm_XTp5_XAB5<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
|
||||
string asmstr, InstrItinClass itin, list<dag> pattern>
|
||||
: I<opcode, OOL, IOL, asmstr, itin>, XFormMemOp {
|
||||
bits<5> XTp;
|
||||
bits<5> A;
|
||||
bits<5> B;
|
||||
|
||||
let Pattern = pattern;
|
||||
let Inst{6-9} = XTp{3-0};
|
||||
let Inst{10} = XTp{4};
|
||||
let Inst{11-15} = A;
|
||||
let Inst{16-20} = B;
|
||||
let Inst{21-30} = xo;
|
||||
let Inst{31} = 0;
|
||||
}
|
||||
|
||||
class 8LS_DForm_R_XTp5_SI34_MEM<bits<6> opcode, dag OOL, dag IOL, string asmstr,
|
||||
InstrItinClass itin, list<dag> pattern>
|
||||
: PI<1, opcode, OOL, IOL, asmstr, itin> {
|
||||
bits<5> XTp;
|
||||
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}; // Imm18
|
||||
|
||||
// The instruction.
|
||||
let Inst{38-41} = XTp{3-0};
|
||||
let Inst{42} = XTp{4};
|
||||
let Inst{43-47} = D_RA{38-34}; // Register #
|
||||
let Inst{48-63} = D_RA{15-0}; // D
|
||||
}
|
||||
|
||||
multiclass 8LS_DForm_R_XTp5_SI34_MEM_p<bits<6> pref, bits<6> opcode, dag OOL,
|
||||
dag IOL, dag PCRel_IOL,
|
||||
string asmstr, InstrItinClass itin> {
|
||||
def NAME : 8LS_DForm_R_XTp5_SI34_MEM<opcode, OOL, IOL,
|
||||
!strconcat(asmstr, ", 0"), itin, []>;
|
||||
def pc : 8LS_DForm_R_XTp5_SI34_MEM<opcode, OOL, PCRel_IOL,
|
||||
!strconcat(asmstr, ", 1"), itin, []>,
|
||||
isPCRel;
|
||||
}
|
||||
|
||||
def PrefixInstrs : Predicate<"Subtarget->hasPrefixInstrs()">;
|
||||
def IsISA3_1 : Predicate<"Subtarget->isISA3_1()">;
|
||||
def PairedVectorMemops : Predicate<"PPCSubTarget->pairedVectorMemops()">;
|
||||
def MMA : Predicate<"PPCSubTarget->hasMMA()">;
|
||||
def PairedVectorMemops : Predicate<"Subtarget->pairedVectorMemops()">;
|
||||
def MMA : Predicate<"Subtarget->hasMMA()">;
|
||||
|
||||
def RCCp {
|
||||
dag AToVSRC = (COPY_TO_REGCLASS $XA, VSRC);
|
||||
@ -672,6 +741,36 @@ let Predicates = [PrefixInstrs] in {
|
||||
}
|
||||
}
|
||||
|
||||
let mayLoad = 1, mayStore = 0, Predicates = [PairedVectorMemops] in {
|
||||
def LXVP : DQForm_XTp5_RA17_MEM<6, 0, (outs vsrprc:$XTp),
|
||||
(ins memrix16:$DQ_RA), "lxvp $XTp, $DQ_RA",
|
||||
IIC_LdStLFD, []>;
|
||||
def LXVPX : XForm_XTp5_XAB5<31, 333, (outs vsrprc:$XTp), (ins memrr:$src),
|
||||
"lxvpx $XTp, $src", IIC_LdStLFD,
|
||||
[(set v4i64:$XTp, (load xaddr:$src))]>;
|
||||
let Predicates = [PrefixInstrs] in {
|
||||
defm PLXVP :
|
||||
8LS_DForm_R_XTp5_SI34_MEM_p<1, 58, (outs vsrprc:$XTp), (ins memri34:$D_RA),
|
||||
(ins memri34_pcrel:$D_RA), "plxvp $XTp, $D_RA",
|
||||
IIC_LdStLFD>;
|
||||
}
|
||||
}
|
||||
|
||||
let mayLoad = 0, mayStore = 1, Predicates = [PairedVectorMemops] in {
|
||||
def STXVP : DQForm_XTp5_RA17_MEM<6, 1, (outs), (ins vsrprc:$XTp,
|
||||
memrix16:$DQ_RA), "stxvp $XTp, $DQ_RA",
|
||||
IIC_LdStLFD, []>;
|
||||
def STXVPX : XForm_XTp5_XAB5<31, 461, (outs), (ins vsrprc:$XTp, memrr:$dst),
|
||||
"stxvpx $XTp, $dst", IIC_LdStLFD,
|
||||
[(store v4i64:$XTp, xaddr:$dst)]>;
|
||||
let Predicates = [PrefixInstrs] in {
|
||||
defm PSTXVP :
|
||||
8LS_DForm_R_XTp5_SI34_MEM_p<1, 62, (outs), (ins vsrprc:$XTp, memri34:$D_RA),
|
||||
(ins vsrprc:$XTp, memri34_pcrel:$D_RA),
|
||||
"pstxvp $XTp, $D_RA", IIC_LdStLFD>;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: We have an added complexity of 500 here. This is only a temporary
|
||||
// solution to have tablegen consider these patterns first. The way we do
|
||||
// addressing for PowerPC is complex depending on available D form, X form, or
|
||||
|
@ -154,8 +154,11 @@ public:
|
||||
case 'r':
|
||||
case 'f':
|
||||
case 'v':
|
||||
if (RegName[1] == 's')
|
||||
if (RegName[1] == 's') {
|
||||
if (RegName[2] == 'p')
|
||||
return RegName + 3;
|
||||
return RegName + 2;
|
||||
}
|
||||
return RegName + 1;
|
||||
case 'c': if (RegName[1] == 'r') return RegName + 2;
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ def sub_eq : SubRegIndex<1, 2>;
|
||||
def sub_un : SubRegIndex<1, 3>;
|
||||
def sub_32 : SubRegIndex<32>;
|
||||
def sub_64 : SubRegIndex<64>;
|
||||
def sub_vsx0 : SubRegIndex<128>;
|
||||
def sub_vsx1 : SubRegIndex<128>;
|
||||
}
|
||||
|
||||
|
||||
@ -94,6 +96,12 @@ class CRBIT<bits<5> num, string n> : PPCReg<n> {
|
||||
let HWEncoding{4-0} = num;
|
||||
}
|
||||
|
||||
// VSR Pairs - One of the 32 paired even-odd consecutive VSRs.
|
||||
class VSRPair<bits<5> num, string n, list<Register> subregs> : PPCReg<n> {
|
||||
let HWEncoding{4-0} = num;
|
||||
let SubRegs = subregs;
|
||||
}
|
||||
|
||||
// General-purpose registers
|
||||
foreach Index = 0-31 in {
|
||||
def R#Index : GPR<Index, "r"#Index>, DwarfRegNum<[-2, Index]>;
|
||||
@ -143,6 +151,23 @@ foreach Index = 32-63 in {
|
||||
def VSX#Index : VSXReg<Index, "vs"#Index>;
|
||||
}
|
||||
|
||||
let SubRegIndices = [sub_vsx0, sub_vsx1] in {
|
||||
// VSR pairs 0 - 15 (corresponding to VSRs 0 - 30 paired with 1 - 31).
|
||||
foreach Index = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 } in {
|
||||
def VSRp#!srl(Index, 1) : VSRPair<!srl(Index, 1), "vsp"#Index,
|
||||
[!cast<VSRL>("VSL"#Index), !cast<VSRL>("VSL"#!add(Index, 1))]>,
|
||||
DwarfRegNum<[0, 0]>;
|
||||
}
|
||||
|
||||
// VSR pairs 16 - 31 (corresponding to VSRs 32 - 62 paired with 33 - 63).
|
||||
foreach Index = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 } in {
|
||||
def VSRp#!add(!srl(Index, 1), 16) :
|
||||
VSRPair<!add(!srl(Index, 1), 16), "vsp"#!add(Index, 32),
|
||||
[!cast<VR>("V"#Index), !cast<VR>("V"#!add(Index, 1))]>,
|
||||
DwarfRegNum<[0, 0]>;
|
||||
}
|
||||
}
|
||||
|
||||
// The representation of r0 when treated as the constant 0.
|
||||
def ZERO : GPR<0, "0">, DwarfRegAlias<R0>;
|
||||
def ZERO8 : GP8<ZERO, "0">, DwarfRegAlias<X0>;
|
||||
@ -372,3 +397,13 @@ def CARRYRC : RegisterClass<"PPC", [i32], 32, (add CARRY, XER)> {
|
||||
let CopyCost = -1;
|
||||
}
|
||||
|
||||
// Allocate in the same order as the underlying VSX registers.
|
||||
def VSRpRC :
|
||||
RegisterClass<"PPC", [v4i64,v4f64,v8i32,v8f32,v16i16,v32i8,v256i1], 128,
|
||||
(add (sequence "VSRp%u", 0, 6),
|
||||
(sequence "VSRp%u", 15, 7), VSRp17, VSRp18,
|
||||
VSRp16, VSRp19, VSRp20, VSRp21, VSRp22, VSRp23,
|
||||
VSRp24, VSRp25, VSRp31, VSRp30, VSRp29, VSRp28,
|
||||
VSRp27, VSRp26)> {
|
||||
let Size = 256;
|
||||
}
|
||||
|
@ -25,6 +25,30 @@
|
||||
# CHECK: pstxv 33, 8589934591(0), 1
|
||||
0x04 0x11 0xff 0xff 0xdc 0x20 0xff 0xff
|
||||
|
||||
# CHECK: lxvp 2, 32(4)
|
||||
0x18 0x44 0x00 0x20
|
||||
|
||||
# CHECK: plxvp 2, -8589934592(0), 1
|
||||
0x04 0x12 0x00 0x00 0xe8 0x40 0x00 0x00
|
||||
|
||||
# CHECK: plxvp 34, 8589934591(3), 0
|
||||
0x04 0x01 0xff 0xff 0xe8 0x63 0xff 0xff
|
||||
|
||||
# CHECK: stxvp 2, 32(4)
|
||||
0x18 0x44 0x00 0x21
|
||||
|
||||
# CHECK: pstxvp 2, -8589934592(0), 1
|
||||
0x04 0x12 0x00 0x00 0xf8 0x40 0x00 0x00
|
||||
|
||||
# CHECK: pstxvp 34, 8589934591(3), 0
|
||||
0x04 0x01 0xff 0xff 0xf8 0x63 0xff 0xff
|
||||
|
||||
# CHECK: lxvpx 2, 3, 4
|
||||
0x7c 0x43 0x22 0x9a
|
||||
|
||||
# CHECK: stxvpx 34, 6, 4
|
||||
0x7c 0x66 0x23 0x9a
|
||||
|
||||
# CHECK: pstfs 1, -134217728(3), 0
|
||||
0x06 0x03 0xf8 0x00 0xd0 0x23 0x00 0x00
|
||||
|
||||
|
@ -23,6 +23,44 @@
|
||||
# CHECK-LE: pstxv 33, -8589934592(31), 0 # encoding: [0x00,0x00,0x02,0x04
|
||||
# CHECK-LE-SAME: 0x00,0x00,0x3f,0xdc]
|
||||
pstxv 33, -8589934592(31), 0
|
||||
# CHECK-BE: lxvp 2, 32(4) # encoding: [0x18,0x44,0x00,0x20]
|
||||
# CHECK-LE: lxvp 2, 32(4) # encoding: [0x20,0x00,0x44,0x18]
|
||||
lxvp 2, 32(4)
|
||||
# CHECK-BE: lxvp 34, 64(4) # encoding: [0x18,0x64,0x00,0x40]
|
||||
# CHECK-LE: lxvp 34, 64(4) # encoding: [0x40,0x00,0x64,0x18]
|
||||
lxvp 34, 64(4)
|
||||
# CHECK-BE: plxvp 2, -8589934592(0), 1 # encoding: [0x04,0x12,0x00,0x00,
|
||||
# CHECK-BE-SAME: 0xe8,0x40,0x00,0x00]
|
||||
# CHECK-LE: plxvp 2, -8589934592(0), 1 # encoding: [0x00,0x00,0x12,0x04,
|
||||
# CHECK-LE-SAME: 0x00,0x00,0x40,0xe8]
|
||||
plxvp 2, -8589934592(0), 1
|
||||
# CHECK-BE: plxvp 34, 8589934591(3), 0 # encoding: [0x04,0x01,0xff,0xff,
|
||||
# CHECK-BE-SAME: 0xe8,0x63,0xff,0xff]
|
||||
# CHECK-LE: plxvp 34, 8589934591(3), 0 # encoding: [0xff,0xff,0x01,0x04,
|
||||
# CHECK-LE-SAME: 0xff,0xff,0x63,0xe8]
|
||||
plxvp 34, 8589934591(3), 0
|
||||
# CHECK-BE: stxvp 2, 32(4) # encoding: [0x18,0x44,0x00,0x21]
|
||||
# CHECK-LE: stxvp 2, 32(4) # encoding: [0x21,0x00,0x44,0x18]
|
||||
stxvp 2, 32(4)
|
||||
# CHECK-BE: stxvp 34, 64(4) # encoding: [0x18,0x64,0x00,0x41]
|
||||
# CHECK-LE: stxvp 34, 64(4) # encoding: [0x41,0x00,0x64,0x18]
|
||||
stxvp 34, 64(4)
|
||||
# CHECK-BE: pstxvp 2, -8589934592(0), 1 # encoding: [0x04,0x12,0x00,0x00,
|
||||
# CHECK-BE-SAME: 0xf8,0x40,0x00,0x00]
|
||||
# CHECK-LE: pstxvp 2, -8589934592(0), 1 # encoding: [0x00,0x00,0x12,0x04
|
||||
# CHECK-LE-SAME: 0x00,0x00,0x40,0xf8]
|
||||
pstxvp 2, -8589934592(0), 1
|
||||
# CHECK-BE: pstxvp 34, 8589934591(3), 0 # encoding: [0x04,0x01,0xff,0xff
|
||||
# CHECK-BE-SAME: 0xf8,0x63,0xff,0xff]
|
||||
# CHECK-LE: pstxvp 34, 8589934591(3), 0 # encoding: [0xff,0xff,0x01,0x04
|
||||
# CHECK-LE-SAME: 0xff,0xff,0x63,0xf8]
|
||||
pstxvp 34, 8589934591(3), 0
|
||||
# CHECK-BE: lxvpx 2, 3, 4 # encoding: [0x7c,0x43,0x22,0x9a]
|
||||
# CHECK-LE: lxvpx 2, 3, 4 # encoding: [0x9a,0x22,0x43,0x7c]
|
||||
lxvpx 2, 3, 4
|
||||
# CHECK-BE: stxvpx 34, 6, 4 # encoding: [0x7c,0x66,0x23,0x9a]
|
||||
# CHECK-LE: stxvpx 34, 6, 4 # encoding: [0x9a,0x23,0x66,0x7c]
|
||||
stxvpx 34, 6, 4
|
||||
# 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
|
||||
|
@ -86,6 +86,7 @@ StringRef llvm::getEnumName(MVT::SimpleValueType T) {
|
||||
case MVT::v32i1: return "MVT::v32i1";
|
||||
case MVT::v64i1: return "MVT::v64i1";
|
||||
case MVT::v128i1: return "MVT::v128i1";
|
||||
case MVT::v256i1: return "MVT::v256i1";
|
||||
case MVT::v512i1: return "MVT::v512i1";
|
||||
case MVT::v1024i1: return "MVT::v1024i1";
|
||||
case MVT::v1i8: return "MVT::v1i8";
|
||||
|
Loading…
Reference in New Issue
Block a user