Skip to content

Commit

Permalink
i#7185 Add missing AArch64 system register enums
Browse files Browse the repository at this point in the history
Add decoding support for the following AArch64 registers:

CONTEXTIDR_EL1
ELR_EL1
SPSR_EL1
TPIDR_EL1

Also add some missing tests for other AArch64 registers.

Fixes: #7185
  • Loading branch information
philramsey-arm committed Jan 15, 2025
1 parent 51ccee3 commit 743d4d2
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 9 deletions.
8 changes: 8 additions & 0 deletions core/ir/aarch64/codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ decode_sysreg(uint imm15)
{
reg_t sysreg;
switch (imm15) {
case 0x4681: sysreg = DR_REG_CONTEXTIDR_EL1; break;
case 0x4201: sysreg = DR_REG_ELR_EL1; break;
case 0x4200: sysreg = DR_REG_SPSR_EL1; break;
case 0x4684: sysreg = DR_REG_TPIDR_EL1; break;
case 0x4000: sysreg = DR_REG_MIDR_EL1; break;
case 0x4005: sysreg = DR_REG_MPIDR_EL1; break;
case 0x4006: sysreg = DR_REG_REVIDR_EL1; break;
Expand Down Expand Up @@ -419,6 +423,10 @@ encode_sysreg(OUT uint *imm15, opnd_t opnd)
{
if (opnd_is_reg(opnd)) {
switch (opnd_get_reg(opnd)) {
case DR_REG_CONTEXTIDR_EL1: *imm15 = 0x4681; break;
case DR_REG_ELR_EL1: *imm15 = 0x4201; break;
case DR_REG_SPSR_EL1: *imm15 = 0x4200; break;
case DR_REG_TPIDR_EL1: *imm15 = 0x4684; break;
case DR_REG_MIDR_EL1: *imm15 = 0x4000; break;
case DR_REG_MPIDR_EL1: *imm15 = 0x4005; break;
case DR_REG_REVIDR_EL1: *imm15 = 0x4006; break;
Expand Down
9 changes: 7 additions & 2 deletions core/ir/aarch64/encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const char *const reg_names[] = {
"id_aa64pfr0_el1", "id_aa64mmfr1_el1", "id_aa64dfr0_el1", "id_aa64zfr0_el1",
"id_aa64pfr1_el1", "id_aa64mmfr2_el1", "midr_el1", "mpidr_el1", "revidr_el1",

"fpmr",
"fpmr", "contextidr_el1", "elr_el1", "spsr_el1", "tpidr_el1"
};


Expand Down Expand Up @@ -203,7 +203,8 @@ const reg_id_t dr_reg_fixer[] = { REG_NULL,
DR_REG_ID_AA64DFR0_EL1, DR_REG_ID_AA64ZFR0_EL1, DR_REG_ID_AA64PFR1_EL1,
DR_REG_ID_AA64MMFR2_EL1, DR_REG_MIDR_EL1, DR_REG_MPIDR_EL1, DR_REG_REVIDR_EL1,

DR_REG_FPMR,
DR_REG_FPMR, DR_REG_CONTEXTIDR_EL1, DR_REG_ELR_EL1, DR_REG_SPSR_EL1,
DR_REG_TPIDR_EL1
};

/* Maps real ISA registers to their corresponding virtual DR_ISA_REGDEPS register.
Expand Down Expand Up @@ -392,6 +393,10 @@ const reg_id_t d_r_reg_id_to_virtual[] = {
DR_REG_VIRT208, /* DR_REG_REVIDR_EL1 */

DR_REG_VIRT209, /* DR_REG_FPMR */
DR_REG_VIRT210, /* DR_REG_CONTEXTIDR_EL1 */
DR_REG_VIRT211, /* DR_REG_ELR_EL1 */
DR_REG_VIRT212, /* DR_REG_SPSR_EL1 */
DR_REG_VIRT213, /* DR_REG_TPIDR_EL1 */
};
/* clang-format on */

Expand Down
12 changes: 8 additions & 4 deletions core/ir/opnd_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -1061,6 +1061,10 @@ enum {
DR_REG_MPIDR_EL1, /**< The "mpidr_el1" register. */
DR_REG_REVIDR_EL1, /**< The "revidr_el1" register. */
DR_REG_FPMR, /**< The "fpmr" register. */
DR_REG_CONTEXTIDR_EL1, /**< The "contextidr_el1" register. */
DR_REG_ELR_EL1, /**< The "elr_el1" register. */
DR_REG_SPSR_EL1, /**< The "spsr_el1" register. */
DR_REG_TPIDR_EL1, /**< The "tpidr_el1" register. */
# endif

/* Aliases below here: */
Expand Down Expand Up @@ -1117,12 +1121,12 @@ enum {
/** Thread Pointer/ID Register, Read-Only, EL0. */
DR_REG_TPIDRRO_EL0 = DR_REG_TPIDRURO,
/* ARMv7 Thread Registers */
DR_REG_CP15_C13_2 = DR_REG_TPIDRURW, /**< User Read/Write Thread ID Register */
DR_REG_CP15_C13_3 = DR_REG_TPIDRURO, /**< User Read-Only Thread ID Register */
DR_REG_CP15_C13_2 = DR_REG_TPIDRURW, /**< User Read/Write Thread ID Register */
DR_REG_CP15_C13_3 = DR_REG_TPIDRURO, /**< User Read-Only Thread ID Register */

# ifdef AARCH64
DR_REG_LAST_VALID_ENUM = DR_REG_FPMR, /**< Last valid register enum */
DR_REG_LAST_ENUM = DR_REG_FPMR, /**< Last value of register enums */
DR_REG_LAST_VALID_ENUM = DR_REG_TPIDR_EL1, /**< Last valid register enum */
DR_REG_LAST_ENUM = DR_REG_TPIDR_EL1, /**< Last value of register enums */
# else
DR_REG_LAST_VALID_ENUM = DR_REG_TPIDRURO, /**< Last valid register enum */
DR_REG_LAST_ENUM = DR_REG_TPIDRURO, /**< Last value of register enums */
Expand Down
2 changes: 1 addition & 1 deletion core/ir/opnd_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -2782,7 +2782,7 @@ reg_get_size(reg_id_t reg)
}
if ((reg >= DR_REG_P0 && reg <= DR_REG_P15) || reg == DR_REG_FFR)
return OPSZ_SVE_PREDLEN_BYTES;
if (reg >= DR_REG_CNTVCT_EL0 && reg <= DR_REG_FPMR)
if (reg >= DR_REG_CNTVCT_EL0 && reg <= DR_REG_TPIDR_EL1)
return OPSZ_8;
if (reg >= DR_REG_NZCV && reg <= DR_REG_FPSR)
return OPSZ_8;
Expand Down
21 changes: 21 additions & 0 deletions suite/tests/api/dis-a64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31743,6 +31743,10 @@ d5380000 : mrs x0, midr_el1 : mrs %midr_el1 -> %x0
d53800a0 : mrs x0, mpidr_el1 : mrs %mpidr_el1 -> %x0
d53800c0 : mrs x0, revidr_el1 : mrs %revidr_el1 -> %x0
d53b4440 : mrs x0, fpmr : mrs %fpmr -> %x0
d538d020 : mrs x0, contextidr_el1 : mrs %contextidr_el1 -> %x0
d5384020 : mrs x0, elr_el1 : mrs %elr_el1 -> %x0
d5384000 : mrs x0, spsr_el1 : mrs %spsr_el1 -> %x0
d538d080 : mrs x0, tpidr_el1 : mrs %tpidr_el1 -> %x0

# MSR <cond>, #<imm> (MSR-I-SI_system)
d50040bf : msr SPSel, #0x0 : msr %spsel $0x00
Expand Down Expand Up @@ -31886,6 +31890,23 @@ d51beffe : msr pmccfiltr_el0, x30 : msr %x30 -> %pmccfiltr
d51c431e : msr spsr_irq, x30 : msr %x30 -> %spsr_irq
d51c433e : msr spsr_abt, x30 : msr %x30 -> %spsr_abt
d51c4360 : msr spsr_fiq, x0 : msr %x0 -> %spsr_fiq
d5180600 : msr x0, id_aa64isar0_el1 : msr %x0 -> %id_aa64isar0_el1
d5180620 : msr x0, id_aa64isar1_el1 : msr %x0 -> %id_aa64isar1_el1
d5180640 : msr x0, id_aa64isar2_el1 : msr %x0 -> %id_aa64isar2_el1
d5180400 : msr x0, id_aa64pfr0_el1 : msr %x0 -> %id_aa64pfr0_el1
d5180720 : msr x0, id_aa64mmfr1_el1 : msr %x0 -> %id_aa64mmfr1_el1
d5180500 : msr x0, id_aa64dfr0_el1 : msr %x0 -> %id_aa64dfr0_el1
d5180480 : msr x0, id_aa64zfr0_el1 : msr %x0 -> %id_aa64zfr0_el1
d5180420 : msr x0, id_aa64pfr1_el1 : msr %x0 -> %id_aa64pfr1_el1
d5180740 : msr x0, id_aa64mmfr2_el1 : msr %x0 -> %id_aa64mmfr2_el1
d5180000 : msr x0, midr_el1 : msr %x0 -> %midr_el1
d51800a0 : msr x0, mpidr_el1 : msr %x0 -> %mpidr_el1
d51800c0 : msr x0, revidr_el1 : msr %x0 -> %revidr_el1
d51b4440 : msr x0, fpmr : msr %x0 -> %fpmr
d518d020 : msr x0, contextidr_el1 : msr %x0 -> %contextidr_el1
d5184020 : msr x0, elr_el1 : msr %x0 -> %elr_el1
d5184000 : msr x0, spsr_el1 : msr %x0 -> %spsr_el1
d518d080 : msr x0, tpidr_el1 : msr %x0 -> %tpidr_el1

# MSUB <Wd>, <Wn>, <Wm>, <Wa> (MSUB-R.RRR-32A_dp_3src)
1b028c20 : msub w0, w1, w2, w3 : msub %w1 %w2 %w3 -> %w0
Expand Down
12 changes: 10 additions & 2 deletions suite/tests/api/ir_aarch64_v80.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ static const reg_id_t systemreg[] = {
DR_REG_MIDR_EL1,
DR_REG_MPIDR_EL1,
DR_REG_REVIDR_EL1,
DR_REG_CONTEXTIDR_EL1,
DR_REG_ELR_EL1,
DR_REG_SPSR_EL1,
DR_REG_TPIDR_EL1,
};
static const size_t sysreg_count = sizeof(systemreg) / sizeof(systemreg[0]);

Expand Down Expand Up @@ -197,7 +201,9 @@ TEST_INSTR(mrs)
"mrs %id_aa64dfr0_el1 -> %x22", "mrs %id_aa64zfr0_el1 -> %x23",
"mrs %id_aa64pfr1_el1 -> %x24", "mrs %id_aa64mmfr2_el1 -> %x25",
"mrs %midr_el1 -> %x26", "mrs %mpidr_el1 -> %x27",
"mrs %revidr_el1 -> %x28"
"mrs %revidr_el1 -> %x28", "mrs %contextidr_el1 -> %x29",
"mrs %elr_el1 -> %x30", "mrs %spsr_el1 -> %x0",
"mrs %tpidr_el1 -> %x1"
/* clang-format on */
);
switch (systemreg[i]) {
Expand Down Expand Up @@ -278,7 +284,9 @@ TEST_INSTR(msr)
"msr %x22 -> %id_aa64dfr0_el1", "msr %x23 -> %id_aa64zfr0_el1",
"msr %x24 -> %id_aa64pfr1_el1", "msr %x25 -> %id_aa64mmfr2_el1",
"msr %x26 -> %midr_el1", "msr %x27 -> %mpidr_el1",
"msr %x28 -> %revidr_el1"
"msr %x28 -> %revidr_el1", "msr %x29 -> %contextidr_el1",
"msr %x30 -> %elr_el1", "msr %x0 -> %spsr_el1",
"msr %x1 -> %tpidr_el1"
/* clang-format on */
);
switch (systemreg[i]) {
Expand Down

0 comments on commit 743d4d2

Please sign in to comment.