Index: lib/Target/PowerPC/PPC.td =================================================================== --- lib/Target/PowerPC/PPC.td +++ lib/Target/PowerPC/PPC.td @@ -155,6 +155,10 @@ def DeprecatedDST : SubtargetFeature<"", "DeprecatedDST", "true", "Treat vector data stream cache control instructions as deprecated">; +def FeatureISA3_0 : SubtargetFeature<"isa-v30-instructions", "IsISA3_0", + "true", + "Enable instructions added in ISA 3.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 less error prone and easier to read. Index: lib/Target/PowerPC/PPCInstr64Bit.td =================================================================== --- lib/Target/PowerPC/PPCInstr64Bit.td +++ lib/Target/PowerPC/PPCInstr64Bit.td @@ -244,12 +244,22 @@ // (EH=1 - see Power ISA 2.07 Book II 4.4.2) def LDARXL : XForm_1<31, 84, (outs g8rc:$rD), (ins memrr:$ptr), "ldarx $rD, $ptr, 1", IIC_LdStLDARX, []>, isDOT; + +let hasExtraSrcRegAllocReq = 1 in +def LDAT : X_RD5_RS5_IM5<31, 614, (outs g8rc:$rD), (ins g8rc:$rA, u5imm:$FC), + "ldat $rD, $rA, $FC", IIC_LdStLoad>, + Requires<[IsISA3_0]>; } let Defs = [CR0], mayStore = 1, hasSideEffects = 0 in def STDCX : XForm_1<31, 214, (outs), (ins g8rc:$rS, memrr:$dst), "stdcx. $rS, $dst", IIC_LdStSTDCX, []>, isDOT; +let mayStore = 1, hasSideEffects = 0 in +def STDAT : X_RD5_RS5_IM5<31, 742, (outs), (ins g8rc:$rS, g8rc:$rA, u5imm:$FC), + "stdat $rS, $rA, $FC", IIC_LdStStore>, + Requires<[IsISA3_0]>; + let Interpretation64Bit = 1, isCodeGenOnly = 1 in { let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in def TCRETURNdi8 :Pseudo< (outs), @@ -905,6 +915,10 @@ "ldux $rD, $addr", IIC_LdStLDUX, []>, RegConstraint<"$addr.ptrreg = $ea_result">, NoEncode<"$ea_result">, isPPC64; + +def LDMX : XForm_1<31, 309, (outs g8rc:$rD), (ins memrr:$src), + "ldmx $rD, $src", IIC_LdStLD, []>, isPPC64, + Requires<[IsISA3_0]>; } } Index: lib/Target/PowerPC/PPCInstrFormats.td =================================================================== --- lib/Target/PowerPC/PPCInstrFormats.td +++ lib/Target/PowerPC/PPCInstrFormats.td @@ -769,6 +769,20 @@ let A = xo2; } +// XForm_base_r3xo for instructions such as P9 atomics where we don't want +// to specify an SDAG pattern for matching. +class X_RD5_RS5_IM5 opcode, bits<10> xo, dag OOL, dag IOL, + string asmstr, InstrItinClass itin> + : XForm_base_r3xo { +} + +class X_BF3 opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, + InstrItinClass itin> + : XForm_17 { + let FRA = 0; + let FRB = 0; +} + // XX*-Form (VSX) class XX1Form opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list pattern> Index: lib/Target/PowerPC/PPCInstrInfo.td =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.td +++ lib/Target/PowerPC/PPCInstrInfo.td @@ -759,6 +759,7 @@ def NaNsFPMath : Predicate<"!TM.Options.NoNaNsFPMath">; def HasBPERMD : Predicate<"PPCSubTarget->hasBPERMD()">; def HasExtDiv : Predicate<"PPCSubTarget->hasExtDiv()">; +def IsISA3_0 : Predicate<"PPCSubTarget->isISA3_0()">; //===----------------------------------------------------------------------===// // PowerPC Multiclass Definitions. @@ -1556,6 +1557,13 @@ def LWARXL : XForm_1<31, 20, (outs gprc:$rD), (ins memrr:$src), "lwarx $rD, $src, 1", IIC_LdStLWARX, []>, isDOT; + +// The atomic instructions use the destination register as well as the next one +// or two registers in order (modulo 31). +let hasExtraSrcRegAllocReq = 1 in +def LWAT : X_RD5_RS5_IM5<31, 582, (outs gprc:$rD), (ins gprc:$rA, u5imm:$FC), + "lwat $rD, $rA, $FC", IIC_LdStLoad>, + Requires<[IsISA3_0]>; } let Defs = [CR0], mayStore = 1, hasSideEffects = 0 in { @@ -1571,6 +1579,11 @@ "stwcx. $rS, $dst", IIC_LdStSTWCX, []>, isDOT; } +let mayStore = 1, hasSideEffects = 0 in +def STWAT : X_RD5_RS5_IM5<31, 710, (outs), (ins gprc:$rS, gprc:$rA, u5imm:$FC), + "stwat $rS, $rA, $FC", IIC_LdStStore>, + Requires<[IsISA3_0]>; + let isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in def TRAP : XForm_24<31, 4, (outs), (ins), "trap", IIC_LdStLoad, [(trap)]>; @@ -2341,6 +2354,9 @@ "mfcr $rT", IIC_SprMFCR>, PPC970_MicroCode, PPC970_Unit_CRU; } // hasExtraSrcRegAllocReq = 1 + +def MCRXRX : X_BF3<31, 576, (outs crrc:$BF), (ins), + "mcrxrx $BF", IIC_BrMCRX>, Requires<[IsISA3_0]>; } // hasSideEffects = 0 // Pseudo instruction to perform FADD in round-to-zero mode. Index: lib/Target/PowerPC/PPCSubtarget.h =================================================================== --- lib/Target/PowerPC/PPCSubtarget.h +++ lib/Target/PowerPC/PPCSubtarget.h @@ -124,6 +124,7 @@ bool HasHTM; bool HasFusion; bool HasFloat128; + bool IsISA3_0; /// When targeting QPX running a stock PPC64 Linux kernel where the stack /// alignment has not been changed, we need to keep the 16-byte alignment @@ -265,6 +266,7 @@ bool hasHTM() const { return HasHTM; } bool hasFusion() const { return HasFusion; } bool hasFloat128() const { return HasFloat128; } + bool isISA3_0() const { return IsISA3_0; } const Triple &getTargetTriple() const { return TargetTriple; } Index: lib/Target/PowerPC/PPCSubtarget.cpp =================================================================== --- lib/Target/PowerPC/PPCSubtarget.cpp +++ lib/Target/PowerPC/PPCSubtarget.cpp @@ -105,6 +105,7 @@ HasHTM = false; HasFusion = false; HasFloat128 = false; + IsISA3_0 = false; } void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) { Index: lib/Target/PowerPC/README_P9.txt =================================================================== --- lib/Target/PowerPC/README_P9.txt +++ lib/Target/PowerPC/README_P9.txt @@ -195,3 +195,18 @@ - Load Vector Word & Splat Indexed: lxvwsx . Likely needs an intrinsic . (set v?:$XT, (int_ppc_vsx_lxvwsx xoaddr:$src)) + +Atomic operations (l[dw]at, st[dw]at): +- Provide custom lowering for common atomic operations to use these + instructions with the correct Function Code +- Ensure the operands are in the correct register (i.e. RT+1, RT+2) +- Provide builtins since not all FC's necessarily have an existing LLVM + atomic operation + +Load Doubleword Monitored (ldmx): +- Investigate whether there are any uses for this. It seems to be related to + Garbage Collection so it isn't likely to be all that useful for most + languages we deal with. + +Move to CR from XER Extended (mcrxrx): +- Is there a use for this in LLVM? Index: test/MC/Disassembler/PowerPC/ppc64-encoding-bookII.txt =================================================================== --- test/MC/Disassembler/PowerPC/ppc64-encoding-bookII.txt +++ test/MC/Disassembler/PowerPC/ppc64-encoding-bookII.txt @@ -33,6 +33,12 @@ # CHECK: stdcx. 2, 3, 4 0x7c 0x43 0x21 0xad +# CHECK: stwat 2, 3, 28 +0x7c 0x43 0xe5 0x8c + +# CHECK: stdat 2, 3, 28 +0x7c 0x43 0xe5 0xcc + # CHECK: ptesync 0x7c 0x40 0x04 0xac @@ -72,6 +78,12 @@ # CHECK: ldarx 2, 3, 4, 1 0x7c 0x43 0x20 0xa9 +# CHECK: lwat 2, 3, 28 +0x7c 0x43 0xe4 0x8c + +# CHECK: ldat 2, 3, 28 +0x7c 0x43 0xe4 0xcc + # CHECK: sync 0x7c 0x00 0x04 0xac Index: test/MC/Disassembler/PowerPC/ppc64-encoding.txt =================================================================== --- test/MC/Disassembler/PowerPC/ppc64-encoding.txt +++ test/MC/Disassembler/PowerPC/ppc64-encoding.txt @@ -151,6 +151,9 @@ # CHECK: ldux 2, 3, 4 0x7c 0x43 0x20 0x6a +# CHECK: ldmx 2, 3, 4 +0x7c 0x43 0x22 0x6a + # CHECK: stb 2, 128(4) 0x98 0x44 0x00 0x80 @@ -658,7 +661,11 @@ # CHECK: mfocrf 16, 8 0x7e 0x10 0x80 0x26 +# CHECK: mcrxrx 7 +0x7f 0x80 0x04 0x80 + # CHECK: mtsrin 10, 12 0x7d 0x40 0x61 0xe4 + # CHECK: mfsrin 10, 12 0x7d 0x40 0x65 0x26 Index: test/MC/PowerPC/ppc64-encoding-bookII.s =================================================================== --- test/MC/PowerPC/ppc64-encoding-bookII.s +++ test/MC/PowerPC/ppc64-encoding-bookII.s @@ -73,10 +73,19 @@ # CHECK-BE: stwcx. 2, 3, 4 # encoding: [0x7c,0x43,0x21,0x2d] # CHECK-LE: stwcx. 2, 3, 4 # encoding: [0x2d,0x21,0x43,0x7c] stwcx. 2, 3, 4 + # CHECK-BE: stdcx. 2, 3, 4 # encoding: [0x7c,0x43,0x21,0xad] # CHECK-LE: stdcx. 2, 3, 4 # encoding: [0xad,0x21,0x43,0x7c] stdcx. 2, 3, 4 +# CHECK-BE: stwat 2, 3, 28 # encoding: [0x7c,0x43,0xe5,0x8c] +# CHECK-LE: stwat 2, 3, 28 # encoding: [0x8c,0xe5,0x43,0x7c] + stwat 2, 3, 28 + +# CHECK-BE: stdat 2, 3, 28 # encoding: [0x7c,0x43,0xe5,0xcc] +# CHECK-LE: stdat 2, 3, 28 # encoding: [0xcc,0xe5,0x43,0x7c] + stdat 2, 3, 28 + # CHECK-BE: ptesync # encoding: [0x7c,0x40,0x04,0xac] # CHECK-LE: ptesync # encoding: [0xac,0x04,0x40,0x7c] sync 2 @@ -131,6 +140,14 @@ # CHECK-LE: ldarx 2, 3, 4, 1 # encoding: [0xa9,0x20,0x43,0x7c] ldarx 2, 3, 4, 1 +# CHECK-BE: lwat 2, 3, 28 # encoding: [0x7c,0x43,0xe4,0x8c] +# CHECK-LE: lwat 2, 3, 28 # encoding: [0x8c,0xe4,0x43,0x7c] + lwat 2, 3, 28 + +# CHECK-BE: ldat 2, 3, 28 # encoding: [0x7c,0x43,0xe4,0xcc] +# CHECK-LE: ldat 2, 3, 28 # encoding: [0xcc,0xe4,0x43,0x7c] + ldat 2, 3, 28 + # CHECK-BE: sync # encoding: [0x7c,0x00,0x04,0xac] # CHECK-LE: sync # encoding: [0xac,0x04,0x00,0x7c] sync Index: test/MC/PowerPC/ppc64-encoding.s =================================================================== --- test/MC/PowerPC/ppc64-encoding.s +++ test/MC/PowerPC/ppc64-encoding.s @@ -197,6 +197,9 @@ # CHECK-BE: ldux 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x6a] # CHECK-LE: ldux 2, 3, 4 # encoding: [0x6a,0x20,0x43,0x7c] ldux 2, 3, 4 +# CHECK-BE: ldmx 2, 3, 4 # encoding: [0x7c,0x43,0x22,0x6a] +# CHECK-LE: ldmx 2, 3, 4 # encoding: [0x6a,0x22,0x43,0x7c] + ldmx 2, 3, 4 # Fixed-point store instructions @@ -833,6 +836,9 @@ # CHECK-BE: mfocrf 16, 8 # encoding: [0x7e,0x10,0x80,0x26] # CHECK-LE: mfocrf 16, 8 # encoding: [0x26,0x80,0x10,0x7e] mfocrf 16, 8 +# CHECK-BE: mcrxrx 7 # encoding: [0x7f,0x80,0x04,0x80] +# CHECK-LE: mcrxrx 7 # encoding: [0x80,0x04,0x80,0x7f] + mcrxrx 7 # Move to/from segment register # CHECK-BE: mtsr 12, 10 # encoding: [0x7d,0x4c,0x01,0xa4]