subg (Subtract with Tag) is an Armv8.5-A memory tagging (MTE)
instruction.  It can be used to subtract an immediate value scaled by
the tag granule from the address in the source register.

gcc/ChangeLog:

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

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 031e621c98a1..0c7aebb838cd 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -8416,6 +8416,23 @@
   [(set_attr "type" "memtag")]
 )
 
+(define_insn "subg"
+  [(set (match_operand:DI 0 "register_operand" "=rk")
+       (ior:DI
+        (and:DI (minus:DI (match_operand:DI 1 "register_operand" "rk")
+                         (match_operand:DI 2 "aarch64_granule16_uimm6" "i"))
+                (const_int -1080863910568919041)) ;; 0xf0ff...
+        (ashift:DI
+         (unspec:QI
+          [(and:QI (lshiftrt:DI (match_dup 1) (const_int 56)) (const_int 15))
+           (match_operand:QI 3 "aarch64_memtag_tag_offset" "i")]
+          UNSPEC_GEN_TAG)
+         (const_int 56))))]
+  "TARGET_MEMTAG"
+  "subg\\t%0, %1, #%2, #%3"
+  [(set_attr "type" "memtag")]
+)
+
 (define_insn "subp"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (minus:DI
-- 
2.43.0

Reply via email to