================
@@ -423,13 +423,95 @@ multiclass AtomicHintPatterns<int Relaxed, int Hint, code 
Pred> {
 }
 
 let AddedComplexity = 15 in {
-  defm : AtomicHintPatternsAddrMode<48, [{ return isAtomicSTSHH_KEEP(N); }]>;
-  defm : AtomicHintPatternsAddrMode<49, [{ return isAtomicSTSHH_STRM(N); }]>;
+  defm : AtomicHintPatternsAddrMode<48, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STSHH_KEEP); }]>;
+  defm : AtomicHintPatternsAddrMode<49, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STSHH_STRM); }]>;
+  defm : AtomicHintPatternsAddrMode<52, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STCPH); }]>;
+  defm : AtomicHintPatternsAddrMode<50, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::SHUH); }]>;
+  defm : AtomicHintPatternsAddrMode<51, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::SHUH_PH); }]>;
+
+  defm : AtomicHintPatterns<1, 48, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STSHH_KEEP); }]>;
+  defm : AtomicHintPatterns<0, 48, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STSHH_KEEP); }]>;
+  defm : AtomicHintPatterns<1, 49, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STSHH_STRM); }]>;
+  defm : AtomicHintPatterns<0, 49, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STSHH_STRM); }]>;
+  defm : AtomicHintPatterns<1, 52, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STCPH); }]>;
+  defm : AtomicHintPatterns<0, 52, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STCPH); }]>;
+  defm : AtomicHintPatterns<1, 50, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::SHUH); }]>;
+  defm : AtomicHintPatterns<0, 50, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::SHUH); }]>;
+  defm : AtomicHintPatterns<1, 51, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::SHUH_PH); }]>;
+  defm : AtomicHintPatterns<0, 51, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::SHUH_PH); }]>;
+}
+
+// Keep the hint and the LSE instruction together until assembly emission.
+// The opcode operand lets all operations and orderings share these pseudos.
+let Size = 8, isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1,
+    mayStore = 1 in {
+  class BaseFetchHintPseudo<RegisterClass dsttype, RegisterClass srctype>
+      : Pseudo<(outs dsttype:$result),
+               (ins srctype:$data, GPR64sp:$addr, i32imm:$opcode,
+                    i32imm:$hint), []>, Sched<[WriteAtomic]>;
+
+  def ATOMIC_FETCH_HINT_W : BaseFetchHintPseudo<GPR32common, GPR32>;
+  def ATOMIC_FETCH_HINT_X : BaseFetchHintPseudo<GPR64common, GPR64>;
+}
+
+class atomic_hint_fetch<PatFrag Base, code Pred>
+  : PatFrag<(ops node:$ptr, node:$val),
+            (Base node:$ptr, node:$val), Pred> {
+  // TODO: Change once mem.cache_hint supported in GISel
+  let GISelPredicateCode = [{ return false; }];
+}
 
-  defm : AtomicHintPatterns<1, 48, [{ return isAtomicSTSHH_KEEP(N); }]>;
-  defm : AtomicHintPatterns<0, 48, [{ return isAtomicSTSHH_KEEP(N); }]>;
-  defm : AtomicHintPatterns<1, 49, [{ return isAtomicSTSHH_STRM(N); }]>;
-  defm : AtomicHintPatterns<0, 49, [{ return isAtomicSTSHH_STRM(N); }]>;
+// Pass the LSE opcode as an immediate so all operations and orderings can use
+// the same two fetch pseudos.
+class AtomicFetchOpcode<string Inst> : SDNodeXForm<imm,
+  "return CurDAG->getTargetConstant(AArch64::" # Inst #
+  ", SDLoc(N), MVT::i32);">;
+
+multiclass AtomicFetchHintPatternsForOpcode<string Inst, string Op,
+                                          RegisterClass RC, Instruction 
Pseudo> {
+  defvar Base = !cast<PatFrag>(Op);
+  defvar Opcode = AtomicFetchOpcode<Inst>;
+  def : Pat<(atomic_hint_fetch<Base, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::SHUH); }]>
+             GPR64sp:$addr, RC:$data),
+            (Pseudo RC:$data, GPR64sp:$addr, (Opcode (i32 0)), (i32 50))>;
+  def : Pat<(atomic_hint_fetch<Base, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::SHUH_PH); }]>
+             GPR64sp:$addr, RC:$data),
+            (Pseudo RC:$data, GPR64sp:$addr, (Opcode (i32 0)), (i32 51))>;
+}
+
+multiclass AtomicFetchHintPatternsOrd<string Inst, string Suffix, string Op,
+                                    RegisterClass RC, Instruction Pseudo> {
+  defm : AtomicFetchHintPatternsForOpcode<Inst # Suffix, Op # "_monotonic",
+                                        RC, Pseudo>;
+  defm : AtomicFetchHintPatternsForOpcode<Inst # "A" # Suffix, Op # "_acquire",
+                                        RC, Pseudo>;
+  defm : AtomicFetchHintPatternsForOpcode<Inst # "L" # Suffix, Op # "_release",
+                                        RC, Pseudo>;
+  defm : AtomicFetchHintPatternsForOpcode<Inst # "AL" # Suffix, Op # 
"_acq_rel",
+                                        RC, Pseudo>;
+  defm : AtomicFetchHintPatternsForOpcode<Inst # "AL" # Suffix, Op # 
"_seq_cst",
+                                        RC, Pseudo>;
+}
+
+multiclass AtomicFetchHintPatterns<string Inst, string Op> {
+  defm : AtomicFetchHintPatternsOrd<Inst, "X", Op # "_i64", GPR64,
+                                  ATOMIC_FETCH_HINT_X>;
+  defm : AtomicFetchHintPatternsOrd<Inst, "W", Op # "_i32", GPR32,
+                                  ATOMIC_FETCH_HINT_W>;
+  defm : AtomicFetchHintPatternsOrd<Inst, "H", Op # "_i16", GPR32,
+                                  ATOMIC_FETCH_HINT_W>;
+  defm : AtomicFetchHintPatternsOrd<Inst, "B", Op # "_i8", GPR32,
+                                  ATOMIC_FETCH_HINT_W>;
----------------
kmclaughlin-arm wrote:

```suggestion
  defm : AtomicFetchHintPatternsOrd<Inst, "X", Op # "_i64", GPR64, 
ATOMIC_FETCH_HINT_X>;
  defm : AtomicFetchHintPatternsOrd<Inst, "W", Op # "_i32", GPR32, 
ATOMIC_FETCH_HINT_W>;
  defm : AtomicFetchHintPatternsOrd<Inst, "H", Op # "_i16", GPR32, 
ATOMIC_FETCH_HINT_W>;
  defm : AtomicFetchHintPatternsOrd<Inst, "B", Op # "_i8", GPR32, 
ATOMIC_FETCH_HINT_W>;
```

https://github.com/llvm/llvm-project/pull/227711
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to