summaryrefslogtreecommitdiff
path: root/lib/Target/ARM64/ARM64InstrAtomics.td
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/ARM64/ARM64InstrAtomics.td')
-rw-r--r--lib/Target/ARM64/ARM64InstrAtomics.td80
1 files changed, 80 insertions, 0 deletions
diff --git a/lib/Target/ARM64/ARM64InstrAtomics.td b/lib/Target/ARM64/ARM64InstrAtomics.td
index 0d36e067a5..296f8d216f 100644
--- a/lib/Target/ARM64/ARM64InstrAtomics.td
+++ b/lib/Target/ARM64/ARM64InstrAtomics.td
@@ -242,6 +242,39 @@ def : Pat<(and (ldxr_2 am_noindex:$addr), 0xffff),
def : Pat<(and (ldxr_4 am_noindex:$addr), 0xffffffff),
(SUBREG_TO_REG (i64 0), (LDXRW am_noindex:$addr), sub_32)>;
+// Load-exclusives.
+
+def ldaxr_1 : PatFrag<(ops node:$ptr), (int_arm64_ldaxr node:$ptr), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+
+def ldaxr_2 : PatFrag<(ops node:$ptr), (int_arm64_ldaxr node:$ptr), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+
+def ldaxr_4 : PatFrag<(ops node:$ptr), (int_arm64_ldaxr node:$ptr), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+
+def ldaxr_8 : PatFrag<(ops node:$ptr), (int_arm64_ldaxr node:$ptr), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64;
+}]>;
+
+def : Pat<(ldaxr_1 am_noindex:$addr),
+ (SUBREG_TO_REG (i64 0), (LDAXRB am_noindex:$addr), sub_32)>;
+def : Pat<(ldaxr_2 am_noindex:$addr),
+ (SUBREG_TO_REG (i64 0), (LDAXRH am_noindex:$addr), sub_32)>;
+def : Pat<(ldaxr_4 am_noindex:$addr),
+ (SUBREG_TO_REG (i64 0), (LDAXRW am_noindex:$addr), sub_32)>;
+def : Pat<(ldaxr_8 am_noindex:$addr), (LDAXRX am_noindex:$addr)>;
+
+def : Pat<(and (ldaxr_1 am_noindex:$addr), 0xff),
+ (SUBREG_TO_REG (i64 0), (LDAXRB am_noindex:$addr), sub_32)>;
+def : Pat<(and (ldaxr_2 am_noindex:$addr), 0xffff),
+ (SUBREG_TO_REG (i64 0), (LDAXRH am_noindex:$addr), sub_32)>;
+def : Pat<(and (ldaxr_4 am_noindex:$addr), 0xffffffff),
+ (SUBREG_TO_REG (i64 0), (LDAXRW am_noindex:$addr), sub_32)>;
+
// Store-exclusives.
def stxr_1 : PatFrag<(ops node:$val, node:$ptr),
@@ -264,6 +297,7 @@ def stxr_8 : PatFrag<(ops node:$val, node:$ptr),
return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64;
}]>;
+
def : Pat<(stxr_1 GPR64:$val, am_noindex:$addr),
(STXRB (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
def : Pat<(stxr_2 GPR64:$val, am_noindex:$addr),
@@ -287,6 +321,52 @@ def : Pat<(stxr_2 (and GPR64:$val, 0xffff), am_noindex:$addr),
def : Pat<(stxr_4 (and GPR64:$val, 0xffffffff), am_noindex:$addr),
(STXRW (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
+// Store-release-exclusives.
+
+def stlxr_1 : PatFrag<(ops node:$val, node:$ptr),
+ (int_arm64_stlxr node:$val, node:$ptr), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+
+def stlxr_2 : PatFrag<(ops node:$val, node:$ptr),
+ (int_arm64_stlxr node:$val, node:$ptr), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+
+def stlxr_4 : PatFrag<(ops node:$val, node:$ptr),
+ (int_arm64_stlxr node:$val, node:$ptr), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+
+def stlxr_8 : PatFrag<(ops node:$val, node:$ptr),
+ (int_arm64_stlxr node:$val, node:$ptr), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64;
+}]>;
+
+
+def : Pat<(stlxr_1 GPR64:$val, am_noindex:$addr),
+ (STLXRB (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
+def : Pat<(stlxr_2 GPR64:$val, am_noindex:$addr),
+ (STLXRH (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
+def : Pat<(stlxr_4 GPR64:$val, am_noindex:$addr),
+ (STLXRW (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
+def : Pat<(stlxr_8 GPR64:$val, am_noindex:$addr),
+ (STLXRX GPR64:$val, am_noindex:$addr)>;
+
+def : Pat<(stlxr_1 (zext (and GPR32:$val, 0xff)), am_noindex:$addr),
+ (STLXRB GPR32:$val, am_noindex:$addr)>;
+def : Pat<(stlxr_2 (zext (and GPR32:$val, 0xffff)), am_noindex:$addr),
+ (STLXRH GPR32:$val, am_noindex:$addr)>;
+def : Pat<(stlxr_4 (zext GPR32:$val), am_noindex:$addr),
+ (STLXRW GPR32:$val, am_noindex:$addr)>;
+
+def : Pat<(stlxr_1 (and GPR64:$val, 0xff), am_noindex:$addr),
+ (STLXRB (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
+def : Pat<(stlxr_2 (and GPR64:$val, 0xffff), am_noindex:$addr),
+ (STLXRH (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
+def : Pat<(stlxr_4 (and GPR64:$val, 0xffffffff), am_noindex:$addr),
+ (STLXRW (EXTRACT_SUBREG GPR64:$val, sub_32), am_noindex:$addr)>;
+
// And clear exclusive.