From dbd3e4a9d535704a0d11f9584e05c039ccf8fc1f Mon Sep 17 00:00:00 2001 From: Matthieu Longo Date: Tue, 21 May 2024 17:37:07 +0100 Subject: [PATCH] aarch64: warn on unpredictable results for new rcpc3 instructions 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 | 40 +++++++++- gas/testsuite/gas/aarch64/rcpc3-fail.d | 1 + gas/testsuite/gas/aarch64/rcpc3-fail.l | 86 +++++++++++++++++--- gas/testsuite/gas/aarch64/rcpc3-fail.s | 104 ++++++++++++++++++++++++- gas/testsuite/gas/aarch64/rcpc3.d | 59 +++++++++++--- gas/testsuite/gas/aarch64/rcpc3.s | 42 ++++++++++ 6 files changed, 306 insertions(+), 26 deletions(-) diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index fec17c40a43..73b733ff727 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -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: diff --git a/gas/testsuite/gas/aarch64/rcpc3-fail.d b/gas/testsuite/gas/aarch64/rcpc3-fail.d index 508a27f5a39..e9a63a295e1 100644 --- a/gas/testsuite/gas/aarch64/rcpc3-fail.d +++ b/gas/testsuite/gas/aarch64/rcpc3-fail.d @@ -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 diff --git a/gas/testsuite/gas/aarch64/rcpc3-fail.l b/gas/testsuite/gas/aarch64/rcpc3-fail.l index 4b33c8524e5..96c2f0aee6c 100644 --- a/gas/testsuite/gas/aarch64/rcpc3-fail.l +++ b/gas/testsuite/gas/aarch64/rcpc3-fail.l @@ -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 diff --git a/gas/testsuite/gas/aarch64/rcpc3-fail.s b/gas/testsuite/gas/aarch64/rcpc3-fail.s index 23b9eaaf19a..687bdd7c700 100644 --- a/gas/testsuite/gas/aarch64/rcpc3-fail.s +++ b/gas/testsuite/gas/aarch64/rcpc3-fail.s @@ -1,13 +1,109 @@ .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]! diff --git a/gas/testsuite/gas/aarch64/rcpc3.d b/gas/testsuite/gas/aarch64/rcpc3.d index 4560ed09e5d..575e46e56ba 100644 --- a/gas/testsuite/gas/aarch64/rcpc3.d +++ b/gas/testsuite/gas/aarch64/rcpc3.d @@ -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\]! diff --git a/gas/testsuite/gas/aarch64/rcpc3.s b/gas/testsuite/gas/aarch64/rcpc3.s index 2a877341e41..41026d4ca04 100644 --- a/gas/testsuite/gas/aarch64/rcpc3.s +++ b/gas/testsuite/gas/aarch64/rcpc3.s @@ -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]! -- 2.45.1