Index: llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp =================================================================== --- llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp +++ llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp @@ -290,6 +290,11 @@ return (unsigned) Imm.Val; } + unsigned getACCReg() const { + assert(isACCRegNumber() && "Invalid access!"); + return (unsigned) Imm.Val; + } + unsigned getVSRpEvenReg() const { assert(isVSRpEvenRegNumber() && "Invalid access!"); return (unsigned) Imm.Val >> 1; @@ -407,6 +412,9 @@ (getImm() & 3) == 0); } bool isImmZero() const { return Kind == Immediate && getImm() == 0; } bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); } + bool isACCRegNumber() const { + return Kind == Immediate && isUInt<3>(getImm()); + } bool isVSRpEvenRegNumber() const { return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0); } @@ -510,6 +518,11 @@ Inst.addOperand(MCOperand::createReg(SPERegs[getReg()])); } + void addRegACCRCOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::createReg(ACCRegs[getACCReg()])); + } + void addRegVSRpRCOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()])); Index: llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp =================================================================== --- llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -173,6 +173,12 @@ return decodeRegisterClass(Inst, RegNo, SPERegs); } +static DecodeStatus DecodeACCRCRegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) { + return decodeRegisterClass(Inst, RegNo, ACCRegs); +} + static DecodeStatus DecodeVSRpRCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder) { Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h =================================================================== --- llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h +++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h @@ -124,6 +124,11 @@ #define GET_SUBTARGETINFO_ENUM #include "PPCGenSubtargetInfo.inc" +#define PPC_REGS0_7(X) \ + { \ + X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7 \ + } + #define PPC_REGS0_31(X) \ { \ X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7, X##8, X##9, X##10, X##11, \ @@ -179,8 +184,7 @@ PPC::CR5LT, PPC::CR5GT, PPC::CR5EQ, PPC::CR5UN, \ PPC::CR6LT, PPC::CR6GT, PPC::CR6EQ, PPC::CR6UN, \ PPC::CR7LT, PPC::CR7GT, PPC::CR7EQ, PPC::CR7UN}; \ - static const MCPhysReg CRRegs[8] = { \ - PPC::CR0, PPC::CR1, PPC::CR2, PPC::CR3, \ - PPC::CR4, PPC::CR5, PPC::CR6, PPC::CR7} + static const MCPhysReg CRRegs[8] = PPC_REGS0_7(PPC::CR); \ + static const MCPhysReg ACCRegs[8] = PPC_REGS0_7(PPC::ACC) #endif // LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCTARGETDESC_H Index: llvm/lib/Target/PowerPC/PPCInstrPrefix.td =================================================================== --- llvm/lib/Target/PowerPC/PPCInstrPrefix.td +++ llvm/lib/Target/PowerPC/PPCInstrPrefix.td @@ -580,6 +580,30 @@ isPCRel; } +def PPCRegACCRCAsmOperand : AsmOperandClass { + let Name = "RegACCRC"; let PredicateMethod = "isACCRegNumber"; +} + +def acc : RegisterOperand { + let ParserMatchClass = PPCRegACCRCAsmOperand; +} + +// [PO AS XO2 XO] +class XForm_AT3 opcode, bits<5> xo2, bits<10> xo, dag OOL, dag IOL, + string asmstr, InstrItinClass itin, list pattern> + : I { + bits<3> AT; + + let Pattern = pattern; + + let Inst{6-8} = AT; + let Inst{9-10} = 0; + let Inst{11-15} = xo2; + let Inst{16-20} = 0; + let Inst{21-30} = xo; + let Inst{31} = 0; +} + def PrefixInstrs : Predicate<"Subtarget->hasPrefixInstrs()">; def IsISA3_1 : Predicate<"Subtarget->isISA3_1()">; def PairedVectorMemops : Predicate<"PPCSubTarget->pairedVectorMemops()">; @@ -735,6 +759,25 @@ } } +let Predicates = [MMA] in { + def XXMFACC : + XForm_AT3<31, 0, 177, (outs acc:$ASo), (ins acc:$AS), "xxmfacc $AS", + IIC_VecGeneral, []>, RegConstraint<"$ASo = $AS">, + NoEncode<"$ASo">; + def XXMTACC : + XForm_AT3<31, 1, 177, (outs acc:$AT), (ins acc:$ATi), "xxmtacc $AT", + IIC_VecGeneral, []>, RegConstraint<"$ATi = $AT">, + NoEncode<"$ATi">; + // We define XXSETACCZ as rematerializable to undo CSE of that intrinsic in + // the backend. We avoid CSE here because it generates a copy of the acc + // register and this copy is more expensive than calling the intrinsic again. + let isAsCheapAsAMove = 1, isReMaterializable = 1 in { + def XXSETACCZ : + XForm_AT3<31, 3, 177, (outs acc:$AT), (ins), "xxsetaccz $AT", + IIC_VecGeneral, []>; + } +} + 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", Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.h =================================================================== --- llvm/lib/Target/PowerPC/PPCRegisterInfo.h +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.h @@ -151,6 +151,11 @@ /// register name so that only the number is left. Used by for linux asm. static const char *stripRegisterPrefix(const char *RegName) { switch (RegName[0]) { + case 'a': + if (RegName[1] == 'c') + if (RegName[2] == 'c') + return RegName + 3; + break; case 'r': case 'f': case 'v': Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.td =================================================================== --- llvm/lib/Target/PowerPC/PPCRegisterInfo.td +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.td @@ -18,6 +18,8 @@ def sub_64 : SubRegIndex<64>; def sub_vsx0 : SubRegIndex<128>; def sub_vsx1 : SubRegIndex<128>; +def sub_pair0 : SubRegIndex<256>; +def sub_pair1 : SubRegIndex<256>; } @@ -96,6 +98,12 @@ let HWEncoding{4-0} = num; } +// ACC - One of the 8 512-bit VSX accumulators. +class ACC num, string n, list subregs> : PPCReg { + let HWEncoding{2-0} = num; + let SubRegs = subregs; +} + // VSR Pairs - One of the 32 paired even-odd consecutive VSRs. class VSRPair num, string n, list subregs> : PPCReg { let HWEncoding{4-0} = num; @@ -397,6 +405,21 @@ let CopyCost = -1; } +let SubRegIndices = [sub_pair0, sub_pair1] in { + def ACC0 : ACC<0, "acc0", [VSRp0, VSRp1]>, DwarfRegNum<[0, 0]>; + def ACC1 : ACC<1, "acc1", [VSRp2, VSRp3]>, DwarfRegNum<[0, 0]>; + def ACC2 : ACC<2, "acc2", [VSRp4, VSRp5]>, DwarfRegNum<[0, 0]>; + def ACC3 : ACC<3, "acc3", [VSRp6, VSRp7]>, DwarfRegNum<[0, 0]>; + def ACC4 : ACC<4, "acc4", [VSRp8, VSRp9]>, DwarfRegNum<[0, 0]>; + def ACC5 : ACC<5, "acc5", [VSRp10, VSRp11]>, DwarfRegNum<[0, 0]>; + def ACC6 : ACC<6, "acc6", [VSRp12, VSRp13]>, DwarfRegNum<[0, 0]>; + def ACC7 : ACC<7, "acc7", [VSRp14, VSRp15]>, DwarfRegNum<[0, 0]>; +} +def ACCRC : RegisterClass<"PPC", [v512i1], 128, (add ACC0, ACC1, ACC2, ACC3, + ACC4, ACC5, ACC6, ACC7)> { + let Size = 512; +} + // Allocate in the same order as the underlying VSX registers. def VSRpRC : RegisterClass<"PPC", [v4i64,v4f64,v8i32,v8f32,v16i16,v32i8,v256i1], 128, Index: llvm/test/MC/Disassembler/PowerPC/ppc64-encoding-ISA31.txt =================================================================== --- llvm/test/MC/Disassembler/PowerPC/ppc64-encoding-ISA31.txt +++ llvm/test/MC/Disassembler/PowerPC/ppc64-encoding-ISA31.txt @@ -25,6 +25,15 @@ # CHECK: pstxv 33, 8589934591(0), 1 0x04 0x11 0xff 0xff 0xdc 0x20 0xff 0xff +# CHECK: xxmfacc 0 +0x7c 0x00 0x01 0x62 + +# CHECK: xxmtacc 0 +0x7c 0x01 0x01 0x62 + +# CHECK: xxsetaccz 0 +0x7c 0x03 0x01 0x62 + # CHECK: lxvp 2, 32(4) 0x18 0x44 0x00 0x20 Index: llvm/test/MC/PowerPC/ppc64-encoding-ISA31.s =================================================================== --- llvm/test/MC/PowerPC/ppc64-encoding-ISA31.s +++ llvm/test/MC/PowerPC/ppc64-encoding-ISA31.s @@ -23,6 +23,15 @@ # 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: xxmfacc 2 # encoding: [0x7d,0x00,0x01,0x62] +# CHECK-LE: xxmfacc 2 # encoding: [0x62,0x01,0x00,0x7d] + xxmfacc 2 +# CHECK-BE: xxmtacc 2 # encoding: [0x7d,0x01,0x01,0x62] +# CHECK-LE: xxmtacc 2 # encoding: [0x62,0x01,0x01,0x7d] + xxmtacc 2 +# CHECK-BE: xxsetaccz 1 # encoding: [0x7c,0x83,0x01,0x62] +# CHECK-LE: xxsetaccz 1 # encoding: [0x62,0x01,0x83,0x7c] + xxsetaccz 1 # 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)