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);
(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());
}
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()]));
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
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); \
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);
}
}
+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
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;
}
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>;
}
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]>;
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>;
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;
+}
# 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
# 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
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";