@@ -826,13 +826,12 @@ let Predicates = [BPFNoALU32] in {
826
826
}
827
827
828
828
// Atomic Fetch-and-<add, and, or, xor> operations
829
- class XFALU64<BPFWidthModifer SizeOp, BPFArithOp Opc, string OpcodeStr,
830
- string OpcStr, PatFrag OpNode>
829
+ class XFALU64<BPFWidthModifer SizeOp, BPFArithOp Opc, string OpcodeStr, string OpcStr>
831
830
: TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
832
831
(outs GPR:$dst),
833
832
(ins MEMri:$addr, GPR:$val),
834
833
"$dst = atomic_fetch_"#OpcStr#"(("#OpcodeStr#" *)($addr), $val)",
835
- [(set GPR:$dst, (OpNode ADDRri:$addr, GPR:$val)) ]> {
834
+ []> {
836
835
bits<4> dst;
837
836
bits<20> addr;
838
837
@@ -844,13 +843,12 @@ class XFALU64<BPFWidthModifer SizeOp, BPFArithOp Opc, string OpcodeStr,
844
843
let BPFClass = BPF_STX;
845
844
}
846
845
847
- class XFALU32<BPFWidthModifer SizeOp, BPFArithOp Opc, string OpcodeStr,
848
- string OpcStr, PatFrag OpNode>
846
+ class XFALU32<BPFWidthModifer SizeOp, BPFArithOp Opc, string OpcodeStr, string OpcStr>
849
847
: TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
850
848
(outs GPR32:$dst),
851
849
(ins MEMri:$addr, GPR32:$val),
852
850
"$dst = atomic_fetch_"#OpcStr#"(("#OpcodeStr#" *)($addr), $val)",
853
- [(set GPR32:$dst, (OpNode ADDRri:$addr, GPR32:$val)) ]> {
851
+ []> {
854
852
bits<4> dst;
855
853
bits<20> addr;
856
854
@@ -864,26 +862,122 @@ class XFALU32<BPFWidthModifer SizeOp, BPFArithOp Opc, string OpcodeStr,
864
862
865
863
let Constraints = "$dst = $val" in {
866
864
let Predicates = [BPFHasALU32], DecoderNamespace = "BPFALU32" in {
867
- def XFADDW32 : XFALU32<BPF_W, BPF_ADD, "u32", "add", atomic_load_add_i32 >;
868
- def XFANDW32 : XFALU32<BPF_W, BPF_AND, "u32", "and", atomic_load_and_i32 >;
869
- def XFORW32 : XFALU32<BPF_W, BPF_OR, "u32", "or", atomic_load_or_i32 >;
870
- def XFXORW32 : XFALU32<BPF_W, BPF_XOR, "u32", "xor", atomic_load_xor_i32 >;
865
+ def XFADDW32 : XFALU32<BPF_W, BPF_ADD, "u32", "add">;
866
+ def XFANDW32 : XFALU32<BPF_W, BPF_AND, "u32", "and">;
867
+ def XFORW32 : XFALU32<BPF_W, BPF_OR, "u32", "or">;
868
+ def XFXORW32 : XFALU32<BPF_W, BPF_XOR, "u32", "xor">;
871
869
}
872
870
873
871
let Predicates = [BPFHasALU32] in {
874
- def XFADDD : XFALU64<BPF_DW, BPF_ADD, "u64", "add", atomic_load_add_i64 >;
872
+ def XFADDD : XFALU64<BPF_DW, BPF_ADD, "u64", "add">;
875
873
}
876
- def XFANDD : XFALU64<BPF_DW, BPF_AND, "u64", "and", atomic_load_and_i64 >;
877
- def XFORD : XFALU64<BPF_DW, BPF_OR, "u64", "or", atomic_load_or_i64 >;
878
- def XFXORD : XFALU64<BPF_DW, BPF_XOR, "u64", "xor", atomic_load_xor_i64 >;
874
+ def XFANDD : XFALU64<BPF_DW, BPF_AND, "u64", "and">;
875
+ def XFORD : XFALU64<BPF_DW, BPF_OR, "u64", "or">;
876
+ def XFXORD : XFALU64<BPF_DW, BPF_XOR, "u64", "xor">;
879
877
}
880
878
881
- // atomic_load_sub can be represented as a neg followed
882
- // by an atomic_load_add.
883
- def : Pat<(atomic_load_sub_i32 ADDRri:$addr, GPR32:$val),
884
- (XFADDW32 ADDRri:$addr, (NEG_32 GPR32:$val))>;
885
- def : Pat<(atomic_load_sub_i64 ADDRri:$addr, GPR:$val),
886
- (XFADDD ADDRri:$addr, (NEG_64 GPR:$val))>;
879
+ let Predicates = [BPFHasALU32] in {
880
+ foreach P = [// add
881
+ [atomic_load_add_i32_monotonic, XADDW32],
882
+ [atomic_load_add_i32_acquire, XFADDW32],
883
+ [atomic_load_add_i32_release, XFADDW32],
884
+ [atomic_load_add_i32_acq_rel, XFADDW32],
885
+ [atomic_load_add_i32_seq_cst, XFADDW32],
886
+ // and
887
+ [atomic_load_and_i32_monotonic, XANDW32],
888
+ [atomic_load_and_i32_acquire, XFANDW32],
889
+ [atomic_load_and_i32_release, XFANDW32],
890
+ [atomic_load_and_i32_acq_rel, XFANDW32],
891
+ [atomic_load_and_i32_seq_cst, XFANDW32],
892
+ // or
893
+ [atomic_load_or_i32_monotonic, XORW32],
894
+ [atomic_load_or_i32_acquire, XFORW32],
895
+ [atomic_load_or_i32_release, XFORW32],
896
+ [atomic_load_or_i32_acq_rel, XFORW32],
897
+ [atomic_load_or_i32_seq_cst, XFORW32],
898
+ // xor
899
+ [atomic_load_xor_i32_monotonic, XXORW32],
900
+ [atomic_load_xor_i32_acquire, XFXORW32],
901
+ [atomic_load_xor_i32_release, XFXORW32],
902
+ [atomic_load_xor_i32_acq_rel, XFXORW32],
903
+ [atomic_load_xor_i32_seq_cst, XFXORW32],
904
+ ] in {
905
+ def : Pat<(P[0] ADDRri:$addr, GPR32:$val), (P[1] ADDRri:$addr, GPR32:$val)>;
906
+ }
907
+
908
+ // atomic_load_sub can be represented as a neg followed
909
+ // by an atomic_load_add.
910
+ foreach P = [[atomic_load_sub_i32_monotonic, XADDW32],
911
+ [atomic_load_sub_i32_acquire, XFADDW32],
912
+ [atomic_load_sub_i32_release, XFADDW32],
913
+ [atomic_load_sub_i32_acq_rel, XFADDW32],
914
+ [atomic_load_sub_i32_seq_cst, XFADDW32],
915
+ ] in {
916
+ def : Pat<(P[0] ADDRri:$addr, GPR32:$val), (P[1] ADDRri:$addr, (NEG_32 GPR32:$val))>;
917
+ }
918
+
919
+ foreach P = [// add
920
+ [atomic_load_add_i64_monotonic, XADDD],
921
+ [atomic_load_add_i64_acquire, XFADDD],
922
+ [atomic_load_add_i64_release, XFADDD],
923
+ [atomic_load_add_i64_acq_rel, XFADDD],
924
+ [atomic_load_add_i64_seq_cst, XFADDD],
925
+ ] in {
926
+ def : Pat<(P[0] ADDRri:$addr, GPR:$val), (P[1] ADDRri:$addr, GPR:$val)>;
927
+ }
928
+ }
929
+
930
+ foreach P = [[atomic_load_sub_i64_monotonic, XADDD],
931
+ [atomic_load_sub_i64_acquire, XFADDD],
932
+ [atomic_load_sub_i64_release, XFADDD],
933
+ [atomic_load_sub_i64_acq_rel, XFADDD],
934
+ [atomic_load_sub_i64_seq_cst, XFADDD],
935
+ ] in {
936
+ def : Pat<(P[0] ADDRri:$addr, GPR:$val), (P[1] ADDRri:$addr, (NEG_64 GPR:$val))>;
937
+ }
938
+
939
+ // Borrow the idea from X86InstrFragments.td
940
+ class binop_no_use<SDPatternOperator operator>
941
+ : PatFrag<(ops node:$A, node:$B),
942
+ (operator node:$A, node:$B),
943
+ [{ return SDValue(N, 0).use_empty(); }]>;
944
+
945
+ class binop_has_use<SDPatternOperator operator>
946
+ : PatFrag<(ops node:$A, node:$B),
947
+ (operator node:$A, node:$B),
948
+ [{ return !SDValue(N, 0).use_empty(); }]>;
949
+
950
+ foreach op = [add, and, or, xor] in {
951
+ def atomic_load_ # op # _i64_monotonic_nu:
952
+ binop_no_use <!cast<SDPatternOperator>("atomic_load_"#op# _i64_monotonic)>;
953
+ def atomic_load_ # op # _i64_monotonic_hu:
954
+ binop_has_use<!cast<SDPatternOperator>("atomic_load_"#op# _i64_monotonic)>;
955
+ }
956
+
957
+ foreach P = [// and
958
+ [atomic_load_and_i64_monotonic_nu, XANDD],
959
+ [atomic_load_and_i64_monotonic_hu, XFANDD],
960
+ [atomic_load_and_i64_acquire, XFANDD],
961
+ [atomic_load_and_i64_release, XFANDD],
962
+ [atomic_load_and_i64_acq_rel, XFANDD],
963
+ [atomic_load_and_i64_seq_cst, XFANDD],
964
+ // or
965
+ [atomic_load_or_i64_monotonic_nu, XORD],
966
+ [atomic_load_or_i64_monotonic_hu, XFORD],
967
+ [atomic_load_or_i64_acquire, XFORD],
968
+ [atomic_load_or_i64_release, XFORD],
969
+ [atomic_load_or_i64_acq_rel, XFORD],
970
+ [atomic_load_or_i64_seq_cst, XFORD],
971
+ // xor
972
+ [atomic_load_xor_i64_monotonic_nu, XXORD],
973
+ [atomic_load_xor_i64_monotonic_hu, XFXORD],
974
+ [atomic_load_xor_i64_acquire, XFXORD],
975
+ [atomic_load_xor_i64_release, XFXORD],
976
+ [atomic_load_xor_i64_acq_rel, XFXORD],
977
+ [atomic_load_xor_i64_seq_cst, XFXORD],
978
+ ] in {
979
+ def : Pat<(P[0] ADDRri:$addr, GPR:$val), (P[1] ADDRri:$addr, GPR:$val)>;
980
+ }
887
981
888
982
// Atomic Exchange
889
983
class XCHG<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode>
0 commit comments