On 11/13/24 3:02 PM, Richard Sandiford wrote:
Indu Bhagat <indu.bha...@oracle.com> writes:
Store Allocation Tags (st2g) is an Armv8.5-A memory tagging (MTE)
instruction. It stores an allocation tag to two tag granules of memory.

TBD:
   - Not too sure what is the best way to generate the st2g yet; A
     subsequent patch will emit them in one of the target hooks.
   - the current define_insn may need fixing.  The construct comparing
     the two offsets should rather be defined as a new predicate?

The comparison looks good to me.  It wouldn't be easy to do the same
thing using predicates alone.

However, I'm not sure how much code is prepared to deal with
(mem (unspec ...)), since that isn't a valid address in the normal
aarch64_legitimate_address_p sense.  Since the unspec would act as
a black box anyway, it might be better to use:

    (set (mem:BLK (scratch:DI))
        ...

for the full store (both tags).  Similarly, it probably isn't
useful to describe which value is being stored when the location
of the store isn't known, so it might be better to use:

    (set (mem:BLK (scratch:DI))
         (unspec_volatile:BLK
           [(match_operand:DI 0 ...)
            (match_operand:DI 1 ...)
            (match_operand:DI 2 ...)]
           UNSPECV_...))

This uses unspec_volatile rather than unspec since changing the tag
would affect the validity of surrounding instructions.  That effect
isn't really described by the memory store alone.


Should all type of store tag instructions also be unspec_volatile then ?

Thanks for reviewing.
Indu

Thanks,
Richard


gcc/ChangeLog:

        * config/aarch64/aarch64.md (st2g): New definition.
---
  gcc/config/aarch64/aarch64.md | 20 ++++++++++++++++++++
  1 file changed, 20 insertions(+)

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 1ec872afef71..a2a69a9c0d3e 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -8252,6 +8252,26 @@
    [(set_attr "type" "memtag")]
  )
+;; ST2G updates allocation tags for two memory granules (i.e. 32 bytes) at
+;; once, without zero initialization.
+(define_insn "st2g"
+  [(set (mem:QI (unspec:DI
+        [(plus:DI (match_operand:DI 1 "register_operand" "rk")
+                  (match_operand:DI 2 "aarch64_granule16_simm9" "i"))]
+        UNSPEC_TAG_SPACE))
+       (and:QI (lshiftrt:DI (match_operand:DI 0 "register_operand" "rk")
+                            (const_int 56)) (const_int 15)))
+   (set (mem:QI (unspec:DI
+        [(plus:DI (match_dup 1)
+                  (match_operand:DI 3 "aarch64_granule16_simm9" "i"))]
+        UNSPEC_TAG_SPACE))
+       (and:QI (lshiftrt:DI (match_dup 0)
+                            (const_int 56)) (const_int 15)))]
+  "TARGET_MEMTAG && (INTVAL (operands[2]) - 16 == INTVAL (operands[3]))"
+  "st2g\\t%0, [%1, #%2]"
+  [(set_attr "type" "memtag")]
+)
+
  ;; Load/Store 64-bit (LS64) instructions.
  (define_insn "ld64b"
    [(set (match_operand:V8DI 0 "register_operand" "=r")

Reply via email to