================
@@ -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