@@ -752,26 +752,40 @@ defm LXADD : ATOMIC_LOAD_BINOP<0xc0, 0xc1, "xadd", "atomic_load_add",
752
752
753
753
/* The following multiclass tries to make sure that in code like
754
754
* x.store (immediate op x.load(acquire), release)
755
+ * and
756
+ * x.store (register op x.load(acquire), release)
755
757
* an operation directly on memory is generated instead of wasting a register.
756
758
* It is not automatic as atomic_store/load are only lowered to MOV instructions
757
759
* extremely late to prevent them from being accidentally reordered in the backend
758
760
* (see below the RELEASE_MOV* / ACQUIRE_MOV* pseudo-instructions)
759
761
*/
760
762
multiclass RELEASE_BINOP_MI<string op> {
761
763
def NAME#8mi : I<0, Pseudo, (outs), (ins i8mem:$dst, i8imm:$src),
762
- "#RELEASE_BINOP PSEUDO!",
764
+ "#BINOP "#NAME#"8mi PSEUDO!",
763
765
[(atomic_store_8 addr:$dst, (!cast<PatFrag>(op)
764
766
(atomic_load_8 addr:$dst), (i8 imm:$src)))]>;
767
+ def NAME#8mr : I<0, Pseudo, (outs), (ins i8mem:$dst, GR8:$src),
768
+ "#BINOP "#NAME#"8mr PSEUDO!",
769
+ [(atomic_store_8 addr:$dst, (!cast<PatFrag>(op)
770
+ (atomic_load_8 addr:$dst), GR8:$src))]>;
765
771
// NAME#16 is not generated as 16-bit arithmetic instructions are considered
766
772
// costly and avoided as far as possible by this backend anyway
767
773
def NAME#32mi : I<0, Pseudo, (outs), (ins i32mem:$dst, i32imm:$src),
768
- "#RELEASE_BINOP PSEUDO!",
774
+ "#BINOP "#NAME#"32mi PSEUDO!",
769
775
[(atomic_store_32 addr:$dst, (!cast<PatFrag>(op)
770
776
(atomic_load_32 addr:$dst), (i32 imm:$src)))]>;
777
+ def NAME#32mr : I<0, Pseudo, (outs), (ins i32mem:$dst, GR32:$src),
778
+ "#BINOP "#NAME#"32mr PSEUDO!",
779
+ [(atomic_store_32 addr:$dst, (!cast<PatFrag>(op)
780
+ (atomic_load_32 addr:$dst), GR32:$src))]>;
771
781
def NAME#64mi32 : I<0, Pseudo, (outs), (ins i64mem:$dst, i64i32imm:$src),
772
- "#RELEASE_BINOP PSEUDO!",
782
+ "#BINOP "#NAME#"64mi32 PSEUDO!",
773
783
[(atomic_store_64 addr:$dst, (!cast<PatFrag>(op)
774
784
(atomic_load_64 addr:$dst), (i64immSExt32:$src)))]>;
785
+ def NAME#64mr : I<0, Pseudo, (outs), (ins i64mem:$dst, GR64:$src),
786
+ "#BINOP "#NAME#"64mr PSEUDO!",
787
+ [(atomic_store_64 addr:$dst, (!cast<PatFrag>(op)
788
+ (atomic_load_64 addr:$dst), GR64:$src))]>;
775
789
}
776
790
defm RELEASE_ADD : RELEASE_BINOP_MI<"add">;
777
791
defm RELEASE_AND : RELEASE_BINOP_MI<"and">;
@@ -780,18 +794,41 @@ defm RELEASE_XOR : RELEASE_BINOP_MI<"xor">;
780
794
// Note: we don't deal with sub, because substractions of constants are
781
795
// optimized into additions before this code can run
782
796
797
+ // Same as above, but for floating-point.
798
+ // FIXME: imm version.
799
+ // FIXME: Version that doesn't clobber $src, using AVX's VADDSS.
800
+ // FIXME: This could also handle SIMD operations with *ps and *pd instructions.
801
+ let usesCustomInserter = 1 in {
802
+ multiclass RELEASE_FP_BINOP_MI<string op> {
803
+ def NAME#32mr : I<0, Pseudo, (outs), (ins i32mem:$dst, FR32:$src),
804
+ "#BINOP "#NAME#"32mr PSEUDO!",
805
+ [(atomic_store_32 addr:$dst,
806
+ (i32 (bitconvert (!cast<PatFrag>(op)
807
+ (f32 (bitconvert (i32 (atomic_load_32 addr:$dst)))),
808
+ FR32:$src))))]>, Requires<[HasSSE1]>;
809
+ def NAME#64mr : I<0, Pseudo, (outs), (ins i64mem:$dst, FR64:$src),
810
+ "#BINOP "#NAME#"64mr PSEUDO!",
811
+ [(atomic_store_64 addr:$dst,
812
+ (i64 (bitconvert (!cast<PatFrag>(op)
813
+ (f64 (bitconvert (i64 (atomic_load_64 addr:$dst)))),
814
+ FR64:$src))))]>, Requires<[HasSSE2]>;
815
+ }
816
+ defm RELEASE_FADD : RELEASE_FP_BINOP_MI<"fadd">;
817
+ // FIXME: Add fsub, fmul, fdiv, ...
818
+ }
819
+
783
820
multiclass RELEASE_UNOP<dag dag8, dag dag16, dag dag32, dag dag64> {
784
821
def NAME#8m : I<0, Pseudo, (outs), (ins i8mem:$dst),
785
- "#RELEASE_UNOP PSEUDO!",
822
+ "#UNOP "#NAME#"8m PSEUDO!",
786
823
[(atomic_store_8 addr:$dst, dag8)]>;
787
824
def NAME#16m : I<0, Pseudo, (outs), (ins i16mem:$dst),
788
- "#RELEASE_UNOP PSEUDO!",
825
+ "#UNOP "#NAME#"16m PSEUDO!",
789
826
[(atomic_store_16 addr:$dst, dag16)]>;
790
827
def NAME#32m : I<0, Pseudo, (outs), (ins i32mem:$dst),
791
- "#RELEASE_UNOP PSEUDO!",
828
+ "#UNOP "#NAME#"32m PSEUDO!",
792
829
[(atomic_store_32 addr:$dst, dag32)]>;
793
830
def NAME#64m : I<0, Pseudo, (outs), (ins i64mem:$dst),
794
- "#RELEASE_UNOP PSEUDO!",
831
+ "#UNOP "#NAME#"64m PSEUDO!",
795
832
[(atomic_store_64 addr:$dst, dag64)]>;
796
833
}
797
834
@@ -821,42 +858,42 @@ defm RELEASE_NOT : RELEASE_UNOP<
821
858
*/
822
859
823
860
def RELEASE_MOV8mi : I<0, Pseudo, (outs), (ins i8mem:$dst, i8imm:$src),
824
- "#RELEASE_MOV PSEUDO !",
861
+ "#RELEASE_MOV8mi PSEUDO!",
825
862
[(atomic_store_8 addr:$dst, (i8 imm:$src))]>;
826
863
def RELEASE_MOV16mi : I<0, Pseudo, (outs), (ins i16mem:$dst, i16imm:$src),
827
- "#RELEASE_MOV PSEUDO !",
864
+ "#RELEASE_MOV16mi PSEUDO!",
828
865
[(atomic_store_16 addr:$dst, (i16 imm:$src))]>;
829
866
def RELEASE_MOV32mi : I<0, Pseudo, (outs), (ins i32mem:$dst, i32imm:$src),
830
- "#RELEASE_MOV PSEUDO !",
867
+ "#RELEASE_MOV32mi PSEUDO!",
831
868
[(atomic_store_32 addr:$dst, (i32 imm:$src))]>;
832
869
def RELEASE_MOV64mi32 : I<0, Pseudo, (outs), (ins i64mem:$dst, i64i32imm:$src),
833
- "#RELEASE_MOV PSEUDO !",
870
+ "#RELEASE_MOV64mi32 PSEUDO!",
834
871
[(atomic_store_64 addr:$dst, i64immSExt32:$src)]>;
835
872
836
873
def RELEASE_MOV8mr : I<0, Pseudo, (outs), (ins i8mem :$dst, GR8 :$src),
837
- "#RELEASE_MOV PSEUDO!",
874
+ "#RELEASE_MOV8mr PSEUDO!",
838
875
[(atomic_store_8 addr:$dst, GR8 :$src)]>;
839
876
def RELEASE_MOV16mr : I<0, Pseudo, (outs), (ins i16mem:$dst, GR16:$src),
840
- "#RELEASE_MOV PSEUDO!",
877
+ "#RELEASE_MOV16mr PSEUDO!",
841
878
[(atomic_store_16 addr:$dst, GR16:$src)]>;
842
879
def RELEASE_MOV32mr : I<0, Pseudo, (outs), (ins i32mem:$dst, GR32:$src),
843
- "#RELEASE_MOV PSEUDO!",
880
+ "#RELEASE_MOV32mr PSEUDO!",
844
881
[(atomic_store_32 addr:$dst, GR32:$src)]>;
845
882
def RELEASE_MOV64mr : I<0, Pseudo, (outs), (ins i64mem:$dst, GR64:$src),
846
- "#RELEASE_MOV PSEUDO!",
883
+ "#RELEASE_MOV64mr PSEUDO!",
847
884
[(atomic_store_64 addr:$dst, GR64:$src)]>;
848
885
849
886
def ACQUIRE_MOV8rm : I<0, Pseudo, (outs GR8 :$dst), (ins i8mem :$src),
850
- "#ACQUIRE_MOV PSEUDO!",
887
+ "#ACQUIRE_MOV8rm PSEUDO!",
851
888
[(set GR8:$dst, (atomic_load_8 addr:$src))]>;
852
889
def ACQUIRE_MOV16rm : I<0, Pseudo, (outs GR16:$dst), (ins i16mem:$src),
853
- "#ACQUIRE_MOV PSEUDO!",
890
+ "#ACQUIRE_MOV16rm PSEUDO!",
854
891
[(set GR16:$dst, (atomic_load_16 addr:$src))]>;
855
892
def ACQUIRE_MOV32rm : I<0, Pseudo, (outs GR32:$dst), (ins i32mem:$src),
856
- "#ACQUIRE_MOV PSEUDO!",
893
+ "#ACQUIRE_MOV32rm PSEUDO!",
857
894
[(set GR32:$dst, (atomic_load_32 addr:$src))]>;
858
895
def ACQUIRE_MOV64rm : I<0, Pseudo, (outs GR64:$dst), (ins i64mem:$src),
859
- "#ACQUIRE_MOV PSEUDO!",
896
+ "#ACQUIRE_MOV64rm PSEUDO!",
860
897
[(set GR64:$dst, (atomic_load_64 addr:$src))]>;
861
898
862
899
//===----------------------------------------------------------------------===//
0 commit comments