Skip to content

Commit f6ea0d6

Browse files
committed
AArch64: SYSL writes its Rt operand, it does not read it
SYSL was generated with CS_AC_READ on Rt, but Rt is the destination. "SYSL <Xt>, #<op1>, <Cn>, <Cm>{, #<op2>}" is the system instruction WITH RESULT, and the Arm ARM names Xt "the 64-bit name of the general-purpose destination register", encoded in the Rt field. Before: sysl x0, #0, c0, c0, #0 operands[0].type: REG = x0 operands[0].access: READ Registers read: x0 After: sysl x0, #0, c0, c0, #0 operands[0].type: REG = x0 operands[0].access: WRITE Registers modified: x0 A consumer tracking register liveness saw a use where there is a definition, which is the unsafe direction: a value written into Xt looked like it was still needed. SYS (without the L) is the opposite direction -- its Xt is a source, and it takes it as the last operand -- and is already CS_AC_READ; it is untouched. Adds the correction to suite/auto-sync/inc_patches so it survives regeneration, plus a regression case. That case asserts regs_write rather than the operand list because two of SYSL's five operands are AARCH64_OP_CIMM, which cstest's operand comparison does not handle (it would take the default branch and report "op type not handled"). regs_write is a field of the `details` mapping, alongside `aarch64` rather than inside it, and cstest compares it through cs_regs_access() -- the exact view this change corrects.
1 parent 64edab7 commit f6ea0d6

3 files changed

Lines changed: 39 additions & 1 deletion

File tree

arch/AArch64/AArch64GenCSMappingInsnOp.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46762,7 +46762,7 @@
4676246762
}},
4676346763
{ /* AARCH64_SYSLxt (7060) - AARCH64_INS_SYSL - sysl $Rt, $op1, $Cn, $Cm, $op2 */
4676446764
{
46765-
{ CS_OP_REG, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST } }, /* Rt */
46765+
{ CS_OP_REG, CS_AC_WRITE, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST } }, /* Rt */
4676646766
{ CS_OP_IMM, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST } }, /* op1 */
4676746767
{ CS_OP_IMM, CS_AC_READ, { CS_DATA_TYPE_i32, CS_DATA_TYPE_LAST } }, /* Cn */
4676846768
{ CS_OP_IMM, CS_AC_READ, { CS_DATA_TYPE_i32, CS_DATA_TYPE_LAST } }, /* Cm */
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# AArch64 SYSL was generated with CS_AC_READ on its Rt operand, but Rt
2+
# is the destination: "SYSL <Xt>, #<op1>, <Cn>, <Cm>{, #<op2>}" is the
3+
# system instruction WITH RESULT, and Xt receives that result. The Arm
4+
# ARM encodes it in the Rt field and names it "the 64-bit name of the
5+
# general-purpose destination register".
6+
#
7+
# Before this patch `sysl x0, #0, c0, c0, #0` reported operands[0] as
8+
# CS_AC_READ and listed x0 under "Registers read" rather than
9+
# "Registers modified", so a consumer tracking register liveness saw a
10+
# use where there is a definition.
11+
#
12+
# SYS (without the L) is the opposite direction -- its Xt is a source --
13+
# and is correctly CS_AC_READ already; it is untouched here.
14+
diff --git a/arch/AArch64/AArch64GenCSMappingInsnOp.inc b/arch/AArch64/AArch64GenCSMappingInsnOp.inc
15+
index 4954eb31..9a9a5b1e 100644
16+
--- a/arch/AArch64/AArch64GenCSMappingInsnOp.inc
17+
+++ b/arch/AArch64/AArch64GenCSMappingInsnOp.inc
18+
@@ -46762,7 +46762,7 @@
19+
}},
20+
{ /* AARCH64_SYSLxt (7060) - AARCH64_INS_SYSL - sysl $Rt, $op1, $Cn, $Cm, $op2 */
21+
{
22+
- { CS_OP_REG, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST } }, /* Rt */
23+
+ { CS_OP_REG, CS_AC_WRITE, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST } }, /* Rt */
24+
{ CS_OP_IMM, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST } }, /* op1 */
25+
{ CS_OP_IMM, CS_AC_READ, { CS_DATA_TYPE_i32, CS_DATA_TYPE_LAST } }, /* Cn */
26+
{ CS_OP_IMM, CS_AC_READ, { CS_DATA_TYPE_i32, CS_DATA_TYPE_LAST } }, /* Cm */

tests/details/aarch64.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,3 +1685,15 @@ test_cases:
16851685
details:
16861686
# Exact-match register lists: x0/x1 only, no NZCV write.
16871687
regs_read: [ x0, x1 ]
1688+
-
1689+
input:
1690+
bytes: [0x00,0x00,0x28,0xd5]
1691+
arch: "CS_ARCH_AARCH64"
1692+
options: [ CS_OPT_DETAIL ]
1693+
address: 0x0
1694+
expected:
1695+
insns:
1696+
-
1697+
asm_text: "sysl x0, #0, c0, c0, #0"
1698+
details:
1699+
regs_write: [ x0 ]

0 commit comments

Comments
 (0)