]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
aarch64: warn on unpredictable results for new rcpc3 instructions
authorMatthieu Longo <matthieu.longo@arm.com>
Tue, 21 May 2024 16:37:07 +0000 (17:37 +0100)
committerRichard Earnshaw <rearnsha@arm.com>
Mon, 10 Jun 2024 15:24:31 +0000 (16:24 +0100)
The previous patch for the feature rcpc3 introduced 4 new operations
(ldiapp, stilp, ldapr, stlr).
The specification mentions some cases of inputs causing unpredictable
results. gas currently fails to diagnose them, and does not emit
warnings. Even if the instruction encoding is valid, the developer
probably wants to know for those cases that the instruction won't have
the expected effect.
- ldiapp & stilp:
  * unpredictable load pair transfer with register overlap
  * unpredictable transfer with writeback
- ldapr & stlr:
  * unpredictable transfer with writeback

This patch also completes the existing relevant tests.

gas/config/tc-aarch64.c
gas/testsuite/gas/aarch64/rcpc3-fail.d
gas/testsuite/gas/aarch64/rcpc3-fail.l
gas/testsuite/gas/aarch64/rcpc3-fail.s
gas/testsuite/gas/aarch64/rcpc3.d
gas/testsuite/gas/aarch64/rcpc3.s

index fec17c40a43e60e294b6aab8976e5926a3c49230..73b733ff7270606033fa1581829ed333107b8d7a 100644 (file)
@@ -3875,7 +3875,7 @@ parse_shifter_operand_reloc (char **str, aarch64_opnd_info *operand,
       if (! aarch64_get_expression (&inst.reloc.exp, str, GE_NO_PREFIX,
                                    REJECT_ABSENT))
        return false;
-      
+
       /* Record the relocation type (use the ADD variant here).  */
       inst.reloc.type = entry->add_type;
       inst.reloc.pc_rel = entry->pc_rel;
@@ -8330,6 +8330,44 @@ warn_unpredictable_ldst (aarch64_instruction *instr, char *str)
        as_warn (_("unpredictable transfer with writeback -- `%s'"), str);
       break;
 
+    case rcpc3:
+      {
+       const int nb_operands = aarch64_num_of_operands (opcode);
+       if (aarch64_get_operand_class (opnds[0].type)
+           == AARCH64_OPND_CLASS_INT_REG)
+         {
+           /* Load Pair transfer with register overlap. */
+           if (nb_operands == 3 && opnds[0].reg.regno == opnds[1].reg.regno)
+             { // ldiapp, stilp
+               as_warn (_("unpredictable load pair transfer with register "
+                          "overlap -- `%s'"),
+                        str);
+             }
+           /* Loading/storing the base register is unpredictable if writeback. */
+           else if ((nb_operands == 2
+                     && opnds[0].reg.regno == opnds[1].addr.base_regno
+                     && opnds[1].addr.base_regno != REG_SP
+                     && opnds[1].addr.writeback)
+                    || (nb_operands == 3
+                        && (opnds[0].reg.regno == opnds[2].addr.base_regno
+                            || opnds[1].reg.regno == opnds[2].addr.base_regno)
+                        && opnds[2].addr.base_regno != REG_SP
+                        && opnds[2].addr.writeback))
+             {
+               if (strcmp (opcode->name, "ldapr") == 0
+                   || strcmp (opcode->name, "ldiapp") == 0)
+                 as_warn (
+                   _("unpredictable transfer with writeback (load) -- `%s'"),
+                   str);
+               else // stlr, stilp
+                 as_warn (
+                   _("unpredictable transfer with writeback (store) -- `%s'"),
+                   str);
+             }
+         }
+      }
+      break;
+
     case ldstpair_off:
     case ldstnapair_offs:
     case ldstpair_indexed:
index 508a27f5a395383ff6d122ab0a7d37f6504988fd..e9a63a295e12a032bb3b8430309f5c30e7ecb895 100644 (file)
@@ -1,3 +1,4 @@
 #name: RCPC3 GPR load/store illegal
+#source: rcpc3-fail.s
 #as: -march=armv8.3-a+rcpc3 -mno-verbose-error
 #error_output: rcpc3-fail.l
index 4b33c8524e58c4c1903c30ce439fbf4c435d06e5..96c2f0aee6c81e08e02a3047f15642135484e27e 100644 (file)
@@ -1,9 +1,77 @@
-[^:]+: Assembler messages:
-[^:]+:3: Error: operand 3 must be an address with post-incrementing by ammount of loaded bytes -- `ldiapp w0,w1,\[x3,#8\]'
-[^:]+:4: Error: operand 3 must be an address with post-incrementing by ammount of loaded bytes -- `ldiapp x0,x1,\[x3,#16\]'
-[^:]+:6: Error: operand 3 must be an address with pre-incrementing with write-back by ammount of stored bytes -- `stilp w0,w1,\[x3,#8\]'
-[^:]+:7: Error: operand 3 must be an address with pre-incrementing with write-back by ammount of stored bytes -- `stilp x0,x1,\[x3,#16\]'
-[^:]+:9: Error: invalid addressing mode at operand 3 -- `stilp w0,w1,\[x3\],#8'
-[^:]+:10: Error: invalid addressing mode at operand 3 -- `stilp x0,x1,\[x3\],#16'
-[^:]+:12: Error: invalid addressing mode at operand 3 -- `ldiapp w0,w1,\[x3,#-8\]!'
-[^:]+:13: Error: invalid addressing mode at operand 3 -- `ldiapp x0,x1,\[x3,#-16\]!'
+.*: Assembler messages:
+.*: Error: operand 3 must be an address with post-incrementing by ammount of loaded bytes -- `ldiapp w0,w1,\[x3,#8\]'
+.*: Error: operand 3 must be an address with post-incrementing by ammount of loaded bytes -- `ldiapp x0,x1,\[x3,#16\]'
+.*: Error: invalid addressing mode at operand 3 -- `ldiapp w0,w1,\[x3,#-8\]!'
+.*: Error: invalid addressing mode at operand 3 -- `ldiapp x0,x1,\[x3,#-16\]!'
+.*: Error: expected an integer or zero register at operand 1 -- `ldiapp sp,x1,\[x3\],#16'
+.*: Error: expected an integer or zero register at operand 1 -- `ldiapp wsp,w1,\[x3\],#8'
+.*: Error: expected an integer or zero register at operand 2 -- `ldiapp x0,sp,\[x3\],#16'
+.*: Error: expected an integer or zero register at operand 2 -- `ldiapp w0,wsp,\[x3\],#8'
+.*: Error: invalid base register at operand 3 -- `ldiapp x0,x1,\[xzr\],#16'
+.*: Error: invalid base register at operand 3 -- `ldiapp x0,x1,\[wzr\],#16'
+.*: Error: expected a 64-bit base register at operand 3 -- `ldiapp w0,w1,\[w3\],#8'
+.*: Error: invalid increment amount at operand 3 -- `ldiapp x0,x1,\[x3\],#8'
+.*: Error: invalid increment amount at operand 3 -- `ldiapp w0,w1,\[x3\],#16'
+.*: Error: operand 3 must be an address with pre-incrementing with write-back by ammount of stored bytes -- `stilp w0,w1,\[x3,#8\]'
+.*: Error: operand 3 must be an address with pre-incrementing with write-back by ammount of stored bytes -- `stilp x0,x1,\[x3,#16\]'
+.*: Error: invalid addressing mode at operand 3 -- `stilp w0,w1,\[x3\],#8'
+.*: Error: invalid addressing mode at operand 3 -- `stilp x0,x1,\[x3\],#16'
+.*: Error: expected an integer or zero register at operand 1 -- `stilp sp,x1,\[x3,#-16\]!'
+.*: Error: expected an integer or zero register at operand 1 -- `stilp wsp,w1,\[x3,#-8\]!'
+.*: Error: expected an integer or zero register at operand 2 -- `stilp x0,sp,\[x3,#-16\]!'
+.*: Error: expected an integer or zero register at operand 2 -- `stilp w0,wsp,\[x3,#-8\]!'
+.*: Error: invalid base register at operand 3 -- `stilp x0,x1,\[xzr,#-16\]!'
+.*: Error: invalid base register at operand 3 -- `stilp x0,x1,\[wzr,#-16\]!'
+.*: Error: expected a 64-bit base register at operand 3 -- `stilp w0,w1,\[w3,#-8\]!'
+.*: Error: invalid increment amount at operand 3 -- `stilp w0,w1,\[x3,#-16\]!'
+.*: Error: invalid increment amount at operand 3 -- `stilp x0,x1,\[x3,#-8\]!'
+.*: Error: invalid increment amount at operand 3 -- `stilp w0,w1,\[x3,#16\]!'
+.*: Error: invalid increment amount at operand 3 -- `stilp x0,x1,\[x3,#8\]!'
+.*: Error: the optional immediate offset can only be 0 at operand 2 -- `ldapr w0,\[x1,#4\]'
+.*: Error: the optional immediate offset can only be 0 at operand 2 -- `ldapr x0,\[x1,#8\]'
+.*: Error: unexpected address writeback at operand 2 -- `ldapr w0,\[x1,#-4\]!'
+.*: Error: unexpected address writeback at operand 2 -- `ldapr x0,\[x1,#-8\]!'
+.*: Error: expected an integer or zero register at operand 1 -- `ldapr wsp,\[x0\],#4'
+.*: Error: expected an integer or zero register at operand 1 -- `ldapr sp,\[x0\],#8'
+.*: Error: invalid base register at operand 2 -- `ldapr x0,\[wzr\],#8'
+.*: Error: invalid base register at operand 2 -- `ldapr x0,\[xzr\],#8'
+.*: Error: expected a 64-bit base register at operand 2 -- `ldapr x0,\[w1\],#8'
+.*: Error: invalid increment amount at operand 2 -- `ldapr w0,\[x1\],#8'
+.*: Error: invalid increment amount at operand 2 -- `ldapr x0,\[x1\],#4'
+.*: Error: unexpected address writeback at operand 2 -- `stlr w0,\[x1\],#4'
+.*: Error: unexpected address writeback at operand 2 -- `stlr x0,\[x1\],#8'
+.*: Error: expected an integer or zero register at operand 1 -- `stlr wsp,\[x0,#-4\]!'
+.*: Error: expected an integer or zero register at operand 1 -- `stlr sp,\[x0,#-8\]!'
+.*: Error: invalid base register at operand 2 -- `stlr x0,\[xzr,#-8\]!'
+.*: Error: invalid base register at operand 2 -- `stlr x0,\[wzr,#-8\]!'
+.*: Error: expected a 64-bit base register at operand 2 -- `stlr x0,\[w1,#-8\]!'
+.*: Error: the optional immediate offset can only be 0 at operand 2 -- `stlr w0,\[x1,#4\]'
+.*: Error: the optional immediate offset can only be 0 at operand 2 -- `stlr x0,\[x1,#8\]'
+.*: Error: invalid increment amount at operand 2 -- `stlr w0,\[x1,#-8\]!'
+.*: Error: invalid increment amount at operand 2 -- `stlr x0,\[x1,#-4\]!'
+.*: Error: invalid increment amount at operand 2 -- `stlr w0,\[x1,#4\]!'
+.*: Error: invalid increment amount at operand 2 -- `stlr x0,\[x1,#8\]!'
+.*: Warning: unpredictable load pair transfer with register overlap -- `ldiapp w0,w0,\[x1\]'
+.*: Warning: unpredictable load pair transfer with register overlap -- `ldiapp x0,x0,\[x1\]'
+.*: Warning: unpredictable load pair transfer with register overlap -- `ldiapp w0,w0,\[x1\],#8'
+.*: Warning: unpredictable load pair transfer with register overlap -- `ldiapp x0,x0,\[x1\],#16'
+.*: Warning: unpredictable load pair transfer with register overlap -- `stilp w0,w0,\[x1\]'
+.*: Warning: unpredictable load pair transfer with register overlap -- `stilp x0,x0,\[x1\]'
+.*: Warning: unpredictable load pair transfer with register overlap -- `stilp w0,w0,\[x1,#-8\]!'
+.*: Warning: unpredictable load pair transfer with register overlap -- `stilp x0,x0,\[x1,#-16\]!'
+.*: Warning: unpredictable transfer with writeback \(load\) -- `ldiapp x0,x1,\[x0\],#16'
+.*: Warning: unpredictable transfer with writeback \(load\) -- `ldiapp x0,x1,\[x1\],#16'
+.*: Warning: unpredictable transfer with writeback \(load\) -- `ldiapp w0,w1,\[x0\],#8'
+.*: Warning: unpredictable transfer with writeback \(load\) -- `ldiapp w0,w1,\[x1\],#8'
+.*: Warning: unpredictable transfer with writeback \(load\) -- `ldapr x0,\[x0\],#8'
+.*: Warning: unpredictable transfer with writeback \(load\) -- `ldapr w0,\[x0\],#4'
+.*: Warning: unpredictable transfer with writeback \(load\) -- `ldapr x1,\[x1\],#8'
+.*: Warning: unpredictable transfer with writeback \(load\) -- `ldapr x30,\[x30\],#8'
+.*: Warning: unpredictable transfer with writeback \(store\) -- `stilp x0,x1,\[x1,#-16\]!'
+.*: Warning: unpredictable transfer with writeback \(store\) -- `stilp w0,w1,\[x1,#-8\]!'
+.*: Warning: unpredictable transfer with writeback \(store\) -- `stilp x0,x1,\[x0,#-16\]!'
+.*: Warning: unpredictable transfer with writeback \(store\) -- `stilp w0,w1,\[x0,#-8\]!'
+.*: Warning: unpredictable transfer with writeback \(store\) -- `stlr x0,\[x0,#-8\]!'
+.*: Warning: unpredictable transfer with writeback \(store\) -- `stlr w0,\[x0,#-4\]!'
+.*: Warning: unpredictable transfer with writeback \(store\) -- `stlr x1,\[x1,#-8\]!'
+.*: Warning: unpredictable transfer with writeback \(store\) -- `stlr x30,\[x30,#-8\]!'
\ No newline at end of file
index 23b9eaaf19af68c9ab7b6e3016c3bf751a0ca9f6..687bdd7c7000a6cfdd65dbf58f576165a8eea6ab 100644 (file)
 .text
-
+       /* Check invalid operands */
+       // wrong addressing mode
        ldiapp w0, w1, [x3, #8]
        ldiapp x0, x1, [x3, #16]
+       ldiapp w0, w1, [x3, #-8]!
+       ldiapp x0, x1, [x3, #-16]!
+       // wrong operand 1
+       ldiapp sp, x1, [x3], #16
+       ldiapp wsp, w1, [x3], #8
+       // wrong operand 2
+       ldiapp x0, sp, [x3], #16
+       ldiapp w0, wsp, [x3], #8
+       // wrong base register
+       ldiapp x0, x1, [xzr], #16
+       ldiapp x0, x1, [wzr], #16
+       ldiapp w0, w1, [w3], #8
+       // wrong increment amount
+       ldiapp x0, x1, [x3], #8
+       ldiapp w0, w1, [x3], #16
 
+       // wrong addressing mode
        stilp w0, w1, [x3, #8]
        stilp x0, x1, [x3, #16]
-
        stilp w0, w1, [x3], #8
        stilp x0, x1, [x3], #16
+       // wrong operand 1
+       stilp sp, x1, [x3, #-16]!
+       stilp wsp, w1, [x3, #-8]!
+       // wrong operand 2
+       stilp x0, sp, [x3, #-16]!
+       stilp w0, wsp, [x3, #-8]!
+       // wrong base register
+       stilp x0, x1, [xzr, #-16]!
+       stilp x0, x1, [wzr, #-16]!
+       stilp w0, w1, [w3, #-8]!
+       // wrong increment amount
+       stilp w0, w1, [x3, #-16]!
+       stilp x0, x1, [x3, #-8]!
+       stilp w0, w1, [x3, #16]!
+       stilp x0, x1, [x3, #8]!
 
-       ldiapp w0, w1, [x3, #-8]!
-       ldiapp x0, x1, [x3, #-16]!
+       // wrong addressing mode
+       ldapr w0, [x1, #4]
+       ldapr x0, [x1, #8]
+       ldapr w0, [x1, #-4]!
+       ldapr x0, [x1, #-8]!
+       // wrong operand 1
+       ldapr wsp, [x0], #4
+       ldapr sp, [x0], #8
+       // wrong base register
+       ldapr x0, [wzr], #8
+       ldapr x0, [xzr], #8
+       ldapr x0, [w1], #8
+       // wrong increment amount
+       ldapr w0, [x1], #8
+       ldapr x0, [x1], #4
+
+       // wrong addressing mode
+       stlr w0, [x1], #4
+       stlr x0, [x1], #8
+       // wrong operand 1
+       stlr wsp, [x0, #-4]!
+       stlr sp, [x0, #-8]!
+       // wrong base register
+       stlr x0, [xzr, #-8]!
+       stlr x0, [wzr, #-8]!
+       stlr x0, [w1, #-8]!
+       // wrong immediate offset
+       stlr w0, [x1, #4]
+       stlr x0, [x1, #8]
+       // wrong increment amount
+       stlr w0, [x1, #-8]!
+       stlr x0, [x1, #-4]!
+       stlr w0, [x1, #4]!
+       stlr x0, [x1, #8]!
+
+       /* Invalid load pair transfer with register overlap */
+       ldiapp w0, w0, [x1]
+       ldiapp x0, x0, [x1]
+       ldiapp w0, w0, [x1], #8
+       ldiapp x0, x0, [x1], #16
+
+       stilp w0, w0, [x1]
+       stilp x0, x0, [x1]
+       stilp w0, w0, [x1, #-8]!
+       stilp x0, x0, [x1, #-16]!
+
+       /* Invalid write back overlap (load)*/
+       ldiapp x0, x1, [x0], #16
+       ldiapp x0, x1, [x1], #16
+       ldiapp w0, w1, [x0], #8
+       ldiapp w0, w1, [x1], #8
+
+       ldapr x0, [x0], #8
+       ldapr w0, [x0], #4
+       ldapr x1, [x1], #8
+       ldapr x30, [x30], #8
+
+       /* Invalid write back overlap (store)*/
+       stilp x0, x1, [x1, #-16]!
+       stilp w0, w1, [x1, #-8]!
+       stilp x0, x1, [x0, #-16]!
+       stilp w0, w1, [x0, #-8]!
+
+       stlr x0, [x0, #-8]!
+       stlr w0, [x0, #-4]!
+       stlr x1, [x1, #-8]!
+       stlr x30, [x30, #-8]!
index 4560ed09e5d1f6eaf5935235d6c806ac66f5111d..575e46e56babf7cf76fa32f387b02bb27c5dd32f 100644 (file)
@@ -1,4 +1,5 @@
 #name: RCPC3 GPR load/store
+#source: rcpc3.s
 #as: -march=armv8.2-a+rcpc3
 #objdump: -dr
 
@@ -7,15 +8,49 @@
 Disassembly of section \.text:
 
 0+ <.*>:
-   0:  d9411860        ldiapp  x0, x1, \[x3\]
-   4:  99411860        ldiapp  w0, w1, \[x3\]
-   8:  d9410860        ldiapp  x0, x1, \[x3\], #16
-   c:  99410860        ldiapp  w0, w1, \[x3\], #8
-  10:  d9011860        stilp   x0, x1, \[x3\]
-  14:  99011860        stilp   w0, w1, \[x3\]
-  18:  d9010860        stilp   x0, x1, \[x3, #-16\]!
-  1c:  99010860        stilp   w0, w1, \[x3, #-8\]!
-  20:  99c00841        ldapr   w1, \[x2\], #4
-  24:  d9c00841        ldapr   x1, \[x2\], #8
-  28:  99800841        stlr    w1, \[x2, #-4\]!
-  2c:  d9800841        stlr    x1, \[x2, #-8\]!
+[^:]+: d9411860        ldiapp  x0, x1, \[x3\]
+[^:]+: 99411860        ldiapp  w0, w1, \[x3\]
+[^:]+: d9410860        ldiapp  x0, x1, \[x3\], #16
+[^:]+: 99410860        ldiapp  w0, w1, \[x3\], #8
+[^:]+: d9410bc0        ldiapp  x0, x1, \[x30\], #16
+[^:]+: d95e081d        ldiapp  x29, x30, \[x0\], #16
+[^:]+: d941087f        ldiapp  xzr, x1, \[x3\], #16
+[^:]+: 9941087f        ldiapp  wzr, w1, \[x3\], #8
+[^:]+: d9410be0        ldiapp  x0, x1, \[sp\], #16
+[^:]+: 99410be0        ldiapp  w0, w1, \[sp\], #8
+[^:]+: d9411800        ldiapp  x0, x1, \[x0\]
+[^:]+: d9411820        ldiapp  x0, x1, \[x1\]
+[^:]+: 99411800        ldiapp  w0, w1, \[x0\]
+[^:]+: 99411820        ldiapp  w0, w1, \[x1\]
+[^:]+: d9011860        stilp   x0, x1, \[x3\]
+[^:]+: 99011860        stilp   w0, w1, \[x3\]
+[^:]+: d9010860        stilp   x0, x1, \[x3, #-16\]!
+[^:]+: 99010860        stilp   w0, w1, \[x3, #-8\]!
+[^:]+: d9011820        stilp   x0, x1, \[x1\]
+[^:]+: d9011800        stilp   x0, x1, \[x0\]
+[^:]+: 99011820        stilp   w0, w1, \[x1\]
+[^:]+: 99011800        stilp   w0, w1, \[x0\]
+[^:]+: b8bfc020        ldapr   w0, \[x1\]
+[^:]+: b8bfc020        ldapr   w0, \[x1\]
+[^:]+: f8bfc020        ldapr   x0, \[x1\]
+[^:]+: f8bfc020        ldapr   x0, \[x1\]
+[^:]+: 99c00841        ldapr   w1, \[x2\], #4
+[^:]+: d9c00841        ldapr   x1, \[x2\], #8
+[^:]+: d9c0081e        ldapr   x30, \[x0\], #8
+[^:]+: d9c00bc0        ldapr   x0, \[x30\], #8
+[^:]+: 99c0083f        ldapr   wzr, \[x1\], #4
+[^:]+: d9c0083f        ldapr   xzr, \[x1\], #8
+[^:]+: 99c00be0        ldapr   w0, \[sp\], #4
+[^:]+: d9c00be0        ldapr   x0, \[sp\], #8
+[^:]+: 889ffc20        stlr    w0, \[x1\]
+[^:]+: 889ffc20        stlr    w0, \[x1\]
+[^:]+: c89ffc20        stlr    x0, \[x1\]
+[^:]+: c89ffc20        stlr    x0, \[x1\]
+[^:]+: 99800841        stlr    w1, \[x2, #-4\]!
+[^:]+: d9800841        stlr    x1, \[x2, #-8\]!
+[^:]+: d980081e        stlr    x30, \[x0, #-8\]!
+[^:]+: d9800bc0        stlr    x0, \[x30, #-8\]!
+[^:]+: 9980083f        stlr    wzr, \[x1, #-4\]!
+[^:]+: d980083f        stlr    xzr, \[x1, #-8\]!
+[^:]+: 99800be0        stlr    w0, \[sp, #-4\]!
+[^:]+: d9800be0        stlr    x0, \[sp, #-8\]!
index 2a877341e4142d620e71939123150fa196eebbc0..41026d4ca044df8b9202f5db4de75ad250970109 100644 (file)
@@ -4,14 +4,56 @@
        ldiapp w0, w1, [x3]
        ldiapp x0, x1, [x3], #16
        ldiapp w0, w1, [x3], #8
+       ldiapp x0, x1, [x30], #16
+       ldiapp x29, x30, [x0], #16
+       ldiapp xzr, x1, [x3], #16
+       ldiapp wzr, w1, [x3], #8
+       ldiapp x0, x1, [sp], #16
+       ldiapp w0, w1, [sp], #8
+       // Note: the following examples have a register overlap between source and
+       // destination registers, but the doc mentions that, in the case where no
+       // offset is specified, writeback is disabled, and so the writeback overlap
+       // for load is fine.
+       ldiapp x0, x1, [x0]
+       ldiapp x0, x1, [x1]
+       ldiapp w0, w1, [x0]
+       ldiapp w0, w1, [x1]
 
        stilp x0, x1, [x3]
        stilp w0, w1, [x3]
        stilp x0, x1, [x3, #-16]!
        stilp w0, w1, [x3, #-8]!
+       // Note: the following examples have a register overlap between source and
+       // destination registers, but the doc mentions that, in the case where no
+       // offset is specified, writeback is disabled, and so the writeback overlap
+       // for store is fine.
+       stilp x0, x1, [x1]
+       stilp x0, x1, [x0]
+       stilp w0, w1, [x1]
+       stilp w0, w1, [x0]
 
+       ldapr w0, [x1]
+       ldapr w0, [x1, #0]
+       ldapr x0, [x1]
+       ldapr x0, [x1, #0]
        ldapr w1, [x2], #4
        ldapr x1, [x2], #8
+       ldapr x30, [x0], #8
+       ldapr x0, [x30], #8
+       ldapr wzr, [x1], #4
+       ldapr xzr, [x1], #8
+       ldapr w0, [sp], #4
+       ldapr x0, [sp], #8
 
+       stlr w0, [x1]
+       stlr w0, [x1, #0]
+       stlr x0, [x1]
+       stlr x0, [x1, #0]
        stlr w1, [x2, #-4]!
        stlr x1, [x2, #-8]!
+       stlr x30, [x0, #-8]!
+       stlr x0, [x30, #-8]!
+       stlr wzr, [x1, #-4]!
+       stlr xzr, [x1, #-8]!
+       stlr w0, [sp, #-4]!
+       stlr x0, [sp, #-8]!