From dcaab1aa8501b75c19f3b2ee908547ac2facabc0 Mon Sep 17 00:00:00 2001 From: Brendan Punsky Date: Thu, 27 Aug 2026 09:59:15 -0400 Subject: [PATCH] rexcode/arm64: system registers get a type instead of being bare i64 They were plain i64 constants handed to op_imm, so any integer typed as one and `inst_mrs(X0, 999999)` compiled fine. Worse, the printer could not tell a system register from an immediate and had to recover the distinction by mnemonic and slot -- MSR's other form holds a PSTATE field selector in the same position, so it keyed off whether operand 1 was a register. System_Register is now its own type with its own Operand_Kind, union member and op_sysreg constructor, exactly as Cond is. The printer's slot logic is gone: the operand knows what it is, so naming it is a case in the same switch that prints every other operand kind. MSR's PSTATE selector is typed PSTATE_FIELD, which is what it always was. It cannot join `Register` itself: that is a u16 with the class in its high byte, leaving 8 bits for the number, and a system register needs 15. Widening it would break `Memory`, which packs two registers plus a displacement and a mode into exactly 64 bits. The constants are also reorganised. They had accreted into overlapping sections -- two "ID registers" groups, three cache groups, a "Batch 5: comprehensive sysreg sweep" banner, and a "hmm let me recompute" note left in a comment. All 231 are now grouped by architectural function (18 groups, alphabetical within each) with their five fields aligned. Verified unchanged against llvm-mc: 222 registers byte-exact through MRS, 8 write-only through MSR, and the PSTATE form still decodes as an immediate rather than a register. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_018UmHLRF11EoWwNWCJ7JGaA --- core/rexcode/isa/arm64/decoder.odin | 2 +- core/rexcode/isa/arm64/encoder.odin | 8 +- core/rexcode/isa/arm64/encoding_types.odin | 4 +- core/rexcode/isa/arm64/mnemonic_builders.odin | 16 +- core/rexcode/isa/arm64/operands.odin | 6 + core/rexcode/isa/arm64/printer.odin | 25 +- core/rexcode/isa/arm64/registers.odin | 670 +++++++++--------- .../tablegen/generated/decode_tables.odin | 2 +- .../tablegen/generated/encode_tables.odin | 2 +- .../isa/arm64/tablegen/instruction_table.odin | 2 +- .../isa/arm64/tables/arm64.encode_forms.bin | Bin 49920 -> 49920 bytes .../isa/arm64/tables/arm64.entries.bin | Bin 49960 -> 49960 bytes .../isa/arm64/tests/pipeline_smoke.odin | 12 +- .../arm64/tools/gen_mnemonic_builders.odin | 17 +- 14 files changed, 375 insertions(+), 391 deletions(-) diff --git a/core/rexcode/isa/arm64/decoder.odin b/core/rexcode/isa/arm64/decoder.odin index 057065941..2784cc8f2 100644 --- a/core/rexcode/isa/arm64/decoder.odin +++ b/core/rexcode/isa/arm64/decoder.odin @@ -203,7 +203,7 @@ extract_operand_inline :: #force_inline proc "contextless" ( case .NZCV_FIELD: return Operand{immediate = i64(word & 0xF), kind = .IMMEDIATE, size = 1} case .SYS_FIELD: - return Operand{immediate = i64((word >> 5) & 0x7FFF), kind = .IMMEDIATE, size = 2} + return Operand{sysreg = System_Register((word >> 5) & 0x7FFF), kind = .SYSTEM_REGISTER, size = 2} case .HINT_FIELD: return Operand{immediate = i64((word >> 5) & 0x7F), kind = .IMMEDIATE, size = 1} case .BARRIER_FIELD: diff --git a/core/rexcode/isa/arm64/encoder.odin b/core/rexcode/isa/arm64/encoder.odin index 5c567489d..d7b5fecab 100644 --- a/core/rexcode/isa/arm64/encoder.odin +++ b/core/rexcode/isa/arm64/encoder.odin @@ -277,8 +277,10 @@ operand_matches_inline :: #force_inline proc "contextless" ( return op.kind == .IMMEDIATE case .IMM_12, .IMM_16, .IMM_8, .IMM_6, .IMM_5, .IMM_4, .IMM_3, .IMM_2, - .NZCV_IMM, .SYS_REG, .HW_SHIFT, .LSE_SIZE, .VEC_SHIFT, .VEC_INDEX: + .NZCV_IMM, .PSTATE_FIELD, .HW_SHIFT, .LSE_SIZE, .VEC_SHIFT, .VEC_INDEX: return op.kind == .IMMEDIATE + case .SYS_REG: + return op.kind == .SYSTEM_REGISTER case .BITMASK_IMM: // The user passes the raw logical mask value; we validate that it // fits the AArch64 bitmask-immediate encoding at the form's width. @@ -390,7 +392,7 @@ pack_operand_inline :: #force_inline proc( return (u32(reg_hw(op.extended.reg)) & 0x1F) << 16 | (u32(op.extended.extend) & 0x7) << 13 | (u32(op.extended.amount) & 0x7) << 10 - case .NONE, .IMMEDIATE, .MEMORY, .RELATIVE, .COND: + case .NONE, .IMMEDIATE, .MEMORY, .RELATIVE, .COND, .SYSTEM_REGISTER: return 0 } @@ -417,7 +419,7 @@ pack_operand_inline :: #force_inline proc( case .NZCV_FIELD: return (u32(op.immediate) & 0xF) << 0 case .SYS_FIELD: - return (u32(op.immediate) & 0x7FFF) << 5 + return (u32(op.sysreg) & 0x7FFF) << 5 case .HINT_FIELD: return (u32(op.immediate) & 0x7F) << 5 case .BARRIER_FIELD: diff --git a/core/rexcode/isa/arm64/encoding_types.odin b/core/rexcode/isa/arm64/encoding_types.odin index a4fe99f41..46d6e8495 100644 --- a/core/rexcode/isa/arm64/encoding_types.odin +++ b/core/rexcode/isa/arm64/encoding_types.odin @@ -150,7 +150,9 @@ Operand_Type :: enum u8 { IMM_4, // 4-bit (HINT, DMB/DSB barrier types, NZCV flags) IMM_2, // 2-bit (FP rounding mode / NEON cmode bits 14:13 etc.) NZCV_IMM, // 4-bit NZCV for CCMP/CCMN immediate forms - SYS_REG, // 16-bit system register encoding (MSR/MRS) + SYS_REG, // MRS/MSR target system register + PSTATE_FIELD, // MSR immediate form: a PSTATE field selector, + // a different namespace from the system registers HW_SHIFT, // 2-bit LSL hw (0/16/32/48) for MOV-immediate BITMASK_IMM, // Logical immediate (bitmask-encoded N:imms:immr) LSE_SIZE, // 2-bit size selector for LSE atomics (00=B 01=H 10=W 11=X) diff --git a/core/rexcode/isa/arm64/mnemonic_builders.odin b/core/rexcode/isa/arm64/mnemonic_builders.odin index 113adcf76..8557d62f2 100644 --- a/core/rexcode/isa/arm64/mnemonic_builders.odin +++ b/core/rexcode/isa/arm64/mnemonic_builders.odin @@ -345,12 +345,12 @@ inst_sevl_none :: #force_inline proc "contextless" () -> Instruction { emit_sevl_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_sevl_none()) } inst_hint_i :: #force_inline proc "contextless" (imm: i64) -> Instruction { return Instruction{mnemonic = .HINT, operand_count = 1, length = 4, ops = {op_imm(imm, 1), {}, {}, {}}} } emit_hint_i :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_hint_i(imm)) } -inst_mrs_r_i :: #force_inline proc "contextless" (dst: Register, imm: i64) -> Instruction { return inst_r_i(.MRS, dst, imm) } -emit_mrs_r_i :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, imm: i64) { append(instructions, inst_mrs_r_i(dst, imm)) } +inst_mrs_r_s :: #force_inline proc "contextless" (dst: Register, sysreg: System_Register) -> Instruction { return Instruction{mnemonic = .MRS, operand_count = 2, length = 4, ops = {op_reg(dst), op_sysreg(sysreg), {}, {}}} } +emit_mrs_r_s :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, sysreg: System_Register) { append(instructions, inst_mrs_r_s(dst, sysreg)) } inst_msr_i_i :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .MSR, operand_count = 2, length = 4, ops = {op_imm(imm, 4), op_imm(imm2, 1), {}, {}}} } -inst_msr_i_r :: #force_inline proc "contextless" (imm: i64, src: Register) -> Instruction { return Instruction{mnemonic = .MSR, operand_count = 2, length = 4, ops = {op_imm(imm, 4), op_reg(src), {}, {}}} } +inst_msr_s_r :: #force_inline proc "contextless" (sysreg: System_Register, src: Register) -> Instruction { return Instruction{mnemonic = .MSR, operand_count = 2, length = 4, ops = {op_sysreg(sysreg), op_reg(src), {}, {}}} } emit_msr_i_i :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_msr_i_i(imm, imm2)) } -emit_msr_i_r :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, src: Register) { append(instructions, inst_msr_i_r(imm, src)) } +emit_msr_s_r :: #force_inline proc(instructions: ^[dynamic]Instruction, sysreg: System_Register, src: Register) { append(instructions, inst_msr_s_r(sysreg, src)) } inst_isb_i :: #force_inline proc "contextless" (imm: i64) -> Instruction { return Instruction{mnemonic = .ISB, operand_count = 1, length = 4, ops = {op_imm(imm, 1), {}, {}, {}}} } emit_isb_i :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_isb_i(imm)) } inst_dsb_i :: #force_inline proc "contextless" (imm: i64) -> Instruction { return Instruction{mnemonic = .DSB, operand_count = 1, length = 4, ops = {op_imm(imm, 1), {}, {}, {}}} } @@ -2216,10 +2216,10 @@ inst_sevl :: inst_sevl_none emit_sevl :: emit_sevl_none inst_hint :: inst_hint_i emit_hint :: emit_hint_i -inst_mrs :: inst_mrs_r_i -emit_mrs :: emit_mrs_r_i -inst_msr :: proc{ inst_msr_i_i, inst_msr_i_r } -emit_msr :: proc{ emit_msr_i_i, emit_msr_i_r } +inst_mrs :: inst_mrs_r_s +emit_mrs :: emit_mrs_r_s +inst_msr :: proc{ inst_msr_i_i, inst_msr_s_r } +emit_msr :: proc{ emit_msr_i_i, emit_msr_s_r } inst_isb :: inst_isb_i emit_isb :: emit_isb_i inst_dsb :: inst_dsb_i diff --git a/core/rexcode/isa/arm64/operands.odin b/core/rexcode/isa/arm64/operands.odin index f1fee81db..86e20675e 100644 --- a/core/rexcode/isa/arm64/operands.odin +++ b/core/rexcode/isa/arm64/operands.odin @@ -28,6 +28,7 @@ Operand_Kind :: enum u8 { SHIFTED_REG, // X reg + shift type + shift amount EXTENDED_REG, // X/W reg + extend + amount COND, // 4-bit condition code (EQ/NE/.../AL/NV) + SYSTEM_REGISTER, // MRS/MSR target, as a packed 15-bit field } Shift_Type :: enum u8 { @@ -104,6 +105,7 @@ Operand :: struct #packed { shifted: Shifted_Reg, // 8 extended: Extended_Reg, // 8 cond: u8, // 1 + sysreg: System_Register, // 2 }, // 12 total because of alignment kind: Operand_Kind, // 1 size: u8, // 1 -- carried width info; meaning varies @@ -151,6 +153,10 @@ op_cond :: #force_inline proc "contextless" (c: Cond) -> Operand { return Operand{cond = u8(c), kind = .COND, size = 1} } +op_sysreg :: #force_inline proc "contextless" (sr: System_Register) -> Operand { + return Operand{sysreg = sr, kind = .SYSTEM_REGISTER, size = 2} +} + // ----------------------------------------------------------------------------- // SVE Z-register builders -- encode the element arrangement in op.size // (B=1, H=2, S=4, D=8). Matcher uses op.size to disambiguate the right diff --git a/core/rexcode/isa/arm64/printer.odin b/core/rexcode/isa/arm64/printer.odin index 85d8c21c9..0e12ed44a 100644 --- a/core/rexcode/isa/arm64/printer.odin +++ b/core/rexcode/isa/arm64/printer.odin @@ -118,20 +118,6 @@ sbprint :: proc( // MOVZ/MOVN/MOVK store the shift as an hw index (0..3 = LSL #0/16/32/48), // which assemblers write as `lsl #16` and omit entirely when it is zero. - // MRS/MSR carry the system register as a packed field, so it has to be - // printed by name -- a bare number is not something an assembler takes. - // MSR's other form takes a PSTATE field selector in the same slot, - // which is a different namespace; it is the one whose second operand - // is an immediate rather than a register. - sysreg_slot, sysreg_ok := -1, false - #partial switch inst.mnemonic { - case .MRS: - sysreg_slot, sysreg_ok = 1, inst.operand_count >= 2 - case .MSR: - sysreg_slot = 0 - sysreg_ok = inst.operand_count >= 2 && inst.ops[1].kind == .REGISTER - } - mov_wide := inst.mnemonic == .MOVZ || inst.mnemonic == .MOVN || inst.mnemonic == .MOVK end_slot := int(inst.operand_count) if mov_wide && end_slot == 3 && inst.ops[2].kind == .IMMEDIATE && inst.ops[2].immediate == 0 { @@ -148,8 +134,6 @@ sbprint :: proc( if mov_wide && slot == 2 { strings.write_string(sb, opts.uppercase ? "LSL #" : "lsl #") write_decimal_u32(sb, u32(inst.ops[slot].immediate) * 16) - } else if slot == sysreg_slot && sysreg_ok { - write_sysreg(sb, inst.ops[slot].immediate, opts.uppercase) } else { write_operand(sb, &inst.ops[slot], &display, opts) } @@ -359,11 +343,11 @@ write_mnemonic :: proc(sb: ^strings.Builder, m: Mnemonic, uppercase: bool) { // A system register by name (`cntvct_el0`), falling back to the raw field // when it is not one we know. @(private="file") -write_sysreg :: proc(sb: ^strings.Builder, value: i64, uppercase: bool) { - name, ok := sysreg_name(value) +write_sysreg :: proc(sb: ^strings.Builder, sr: System_Register, uppercase: bool) { + name, ok := sysreg_name(sr) if !ok { strings.write_byte(sb, '#') - write_signed_decimal(sb, value) + write_signed_decimal(sb, i64(sr)) return } for i in 0 ..< len(name) { @@ -490,6 +474,9 @@ write_operand :: proc( strings.write_byte(sb, '#') write_signed_decimal(sb, op.immediate) + case .SYSTEM_REGISTER: + write_sysreg(sb, op.sysreg, opts.uppercase) + case .COND: c := op.cond & 0xF s := COND_NAMES[c] diff --git a/core/rexcode/isa/arm64/registers.odin b/core/rexcode/isa/arm64/registers.odin index 2ae17eaa1..10e6040d5 100644 --- a/core/rexcode/isa/arm64/registers.odin +++ b/core/rexcode/isa/arm64/registers.odin @@ -103,41 +103,41 @@ V28 :: Register(REG_V | 28); V29 :: Register(REG_V | 29); V30 :: Register(REG_V @(require_results) w_reg :: #force_inline proc "contextless" (n: u8) -> Register { return Register(REG_W | u16(n & 0x1F)) } // ============================================================================= -// AArch64 SYSTEM REGISTERS (named constants for MRS / MSR) +// AArch64 SYSTEM REGISTERS (MRS / MSR) // ============================================================================= // -// The MRS / MSR instructions encode the target system register as a 15-bit -// field at bits 19:5 of the instruction word: +// A system register does not fit `Register`: that is a u16 carrying the class +// in its high byte, which leaves 8 bits for the number, and a system register +// needs 15. Widening it is not free either -- `Memory` packs two of them plus +// a displacement and a mode into exactly 64 bits. So this is its own type +// alongside `Register`, the way `Cond` is, with its own Operand_Kind and its +// own `op_sysreg` constructor. // -// o0 (1 bit) : op0 - 2 (op0 = 2 -> o0=0; op0 = 3 -> o0=1) -// op1 (3 bit) : op1 -// CRn (4 bit) : CRn -// CRm (4 bit) : CRm -// op2 (3 bit) : op2 +// MRS / MSR name their target as a 15-bit field at bits 19:5 of the word, +// packed MSB-first as o0 || op1 || CRn || CRm || op2: // -// concatenated MSB-first: o0 || op1 || CRn || CRm || op2. +// o0 (1 bit) op0 - 2 (op0 = 2 -> 0, op0 = 3 -> 1) +// op1 (3 bits) +// CRn (4 bits) +// CRm (4 bits) +// op2 (3 bits) // -// Users pass these as the immediate operand to `inst_*` builders or by -// hand, e.g.: -// -// MRS X0, NZCV -> op_imm(arm64.NZCV, 2) -// -// The encoder packs the field into SYS_FIELD at bits 19:5 via the standard -// `(imm & 0x7FFF) << 5` mask, so callers can pass either the raw 15-bit -// field value (preferred) or the historical 0x_DA10-style 16-bit form -// (top bit gets masked off). +// Each constant below carries those five fields in its comment, and every +// value is verified byte-exact against llvm-mc. + +System_Register :: distinct u16 // ----------------------------------------------------------------------------- -// Helper for building sysreg field values at compile time. -// sysreg_field(op0, op1, CRn, CRm, op2) = packed 15-bit field -// op0 must be 2 or 3 (the o0 bit = op0 - 2). +// Build a field value from the five architectural numbers, for a register this +// list does not name. op0 must be 2 or 3. // ----------------------------------------------------------------------------- -sysreg_field :: #force_inline proc "contextless" (op0, op1, CRn, CRm, op2: u32) -> i64 { +@(require_results) +sysreg_field :: #force_inline proc "contextless" (op0, op1, CRn, CRm, op2: u16) -> System_Register { o0 := (op0 - 2) & 0x1 - return i64( + return System_Register( (o0 << 14) | - (op1 << 11) | + (op1 << 11) | (CRn << 7) | (CRm << 3) | op2, @@ -145,381 +145,357 @@ sysreg_field :: #force_inline proc "contextless" (op0, op1, CRn, CRm, op2: u32) } // ----------------------------------------------------------------------------- -// Commonly-used named registers (the ones every disassembler knows about). +// Process state, exceptions and stack pointers // ----------------------------------------------------------------------------- -// op0 op1 CRn CRm op2 -NZCV :: i64(0x5A10) // 3 3 4 2 0 -DAIF :: i64(0x5A11) // 3 3 4 2 1 -FPCR :: i64(0x5A20) // 3 3 4 4 0 -FPSR :: i64(0x5A21) // 3 3 4 4 1 -CURRENT_EL :: i64(0x4212) // 3 0 4 2 2 -SP_EL0 :: i64(0x4208) // 3 0 4 1 0 -SP_EL1 :: i64(0x6208) // 3 4 4 1 0 -ELR_EL1 :: i64(0x4201) // 3 0 4 0 1 -ELR_EL2 :: i64(0x6201) // 3 4 4 0 1 -SPSR_EL1 :: i64(0x4200) // 3 0 4 0 0 -SPSR_EL2 :: i64(0x6200) // 3 4 4 0 0 -ESR_EL1 :: i64(0x4290) // 3 0 5 2 0 -ESR_EL2 :: i64(0x6290) // 3 4 5 2 0 -FAR_EL1 :: i64(0x4300) // 3 0 6 0 0 -FAR_EL2 :: i64(0x6300) // 3 4 6 0 0 -TPIDR_EL0 :: i64(0x5E82) // 3 3 13 0 2 -TPIDRRO_EL0 :: i64(0x5E83) // 3 3 13 0 3 -TPIDR_EL1 :: i64(0x4684) // 3 0 13 0 4 (corrected: 3 0 13 0 4 -> 4684 hmm let me recompute) - -// Counters / system identity -CNTFRQ_EL0 :: i64(0x5F00) // 3 3 14 0 0 -CNTPCT_EL0 :: i64(0x5F01) // 3 3 14 0 1 -CNTVCT_EL0 :: i64(0x5F02) // 3 3 14 0 2 -MIDR_EL1 :: i64(0x4000) // 3 0 0 0 0 -MPIDR_EL1 :: i64(0x4005) // 3 0 0 0 5 -DCZID_EL0 :: i64(0x5807) // 3 3 0 0 7 (used by __sve_max_vl-style probes too) -CTR_EL0 :: i64(0x5801) // 3 3 0 0 1 -TCR_EL1 :: i64(0x4102) // 3 0 2 0 2 -SCTLR_EL1 :: i64(0x4080) // 3 0 1 0 0 -VBAR_EL1 :: i64(0x4600) // 3 0 12 0 0 -HCR_EL2 :: i64(0x6088) // 3 4 1 1 0 -TTBR0_EL1 :: i64(0x4100) // 3 0 2 0 0 -TTBR1_EL1 :: i64(0x4101) // 3 0 2 0 1 +// op0 op1 CRn CRm op2 +AFSR0_EL1 :: System_Register(0x4288) // 3 0 5 1 0 +AFSR1_EL1 :: System_Register(0x4289) // 3 0 5 1 1 +CURRENT_EL :: System_Register(0x4212) // 3 0 4 2 2 +DAIF :: System_Register(0x5A11) // 3 3 4 2 1 +ELR_EL1 :: System_Register(0x4201) // 3 0 4 0 1 +ELR_EL2 :: System_Register(0x6201) // 3 4 4 0 1 +ELR_EL3 :: System_Register(0x7201) // 3 6 4 0 1 +ESR_EL1 :: System_Register(0x4290) // 3 0 5 2 0 +ESR_EL2 :: System_Register(0x6290) // 3 4 5 2 0 +FAR_EL1 :: System_Register(0x4300) // 3 0 6 0 0 +FAR_EL2 :: System_Register(0x6300) // 3 4 6 0 0 +ISR_EL1 :: System_Register(0x4608) // 3 0 12 1 0 +NZCV :: System_Register(0x5A10) // 3 3 4 2 0 +SPSR_EL1 :: System_Register(0x4200) // 3 0 4 0 0 +SPSR_EL2 :: System_Register(0x6200) // 3 4 4 0 0 +SPSR_EL3 :: System_Register(0x7200) // 3 6 4 0 0 +SP_EL0 :: System_Register(0x4208) // 3 0 4 1 0 +SP_EL1 :: System_Register(0x6208) // 3 4 4 1 0 +VBAR_EL1 :: System_Register(0x4600) // 3 0 12 0 0 +VBAR_EL2 :: System_Register(0x6600) // 3 4 12 0 0 +VBAR_EL3 :: System_Register(0x7600) // 3 6 12 0 0 // ----------------------------------------------------------------------------- -// Identification registers (ID_AA64*_EL1) -- read-only feature bitmaps +// Floating-point control // ----------------------------------------------------------------------------- -ID_AA64ISAR0_EL1 :: i64(0x4030) // 3 0 0 6 0 -ID_AA64ISAR1_EL1 :: i64(0x4031) // 3 0 0 6 1 -ID_AA64ISAR2_EL1 :: i64(0x4032) // 3 0 0 6 2 -ID_AA64PFR0_EL1 :: i64(0x4020) // 3 0 0 4 0 -ID_AA64PFR1_EL1 :: i64(0x4021) // 3 0 0 4 1 -ID_AA64DFR0_EL1 :: i64(0x4028) // 3 0 0 5 0 -ID_AA64DFR1_EL1 :: i64(0x4029) // 3 0 0 5 1 -ID_AA64MMFR0_EL1 :: i64(0x4038) // 3 0 0 7 0 -ID_AA64MMFR1_EL1 :: i64(0x4039) // 3 0 0 7 1 -ID_AA64MMFR2_EL1 :: i64(0x403A) // 3 0 0 7 2 + +// op0 op1 CRn CRm op2 +FPCR :: System_Register(0x5A20) // 3 3 4 4 0 +FPSR :: System_Register(0x5A21) // 3 3 4 4 1 +MVFR0_EL1 :: System_Register(0x4018) // 3 0 0 3 0 +MVFR1_EL1 :: System_Register(0x4019) // 3 0 0 3 1 +MVFR2_EL1 :: System_Register(0x401A) // 3 0 0 3 2 // ----------------------------------------------------------------------------- -// Performance Monitor Unit (PMU) +// Thread and process identity // ----------------------------------------------------------------------------- -PMCR_EL0 :: i64(0x5CE0) // 3 3 9 12 0 -PMCNTENSET_EL0 :: i64(0x5CE1) // 3 3 9 12 1 -PMCNTENCLR_EL0 :: i64(0x5CE2) // 3 3 9 12 2 -PMOVSCLR_EL0 :: i64(0x5CE3) // 3 3 9 12 3 -PMSWINC_EL0 :: i64(0x5CE4) // 3 3 9 12 4 -PMSELR_EL0 :: i64(0x5CE5) // 3 3 9 12 5 -PMCEID0_EL0 :: i64(0x5CE6) // 3 3 9 12 6 -PMCEID1_EL0 :: i64(0x5CE7) // 3 3 9 12 7 -PMCCNTR_EL0 :: i64(0x5CE8) // 3 3 9 13 0 -PMUSERENR_EL0 :: i64(0x5CF0) // 3 3 9 14 0 + +// op0 op1 CRn CRm op2 +CONTEXTIDR_EL1 :: System_Register(0x4681) // 3 0 13 0 1 +TPIDR2_EL0 :: System_Register(0x5E85) // 3 3 13 0 5 (SME thread pointer 2) +TPIDRRO_EL0 :: System_Register(0x5E83) // 3 3 13 0 3 +TPIDR_EL0 :: System_Register(0x5E82) // 3 3 13 0 2 +TPIDR_EL1 :: System_Register(0x4684) // 3 0 13 0 4 +TPIDR_EL2 :: System_Register(0x6682) // 3 4 13 0 2 +TPIDR_EL3 :: System_Register(0x7682) // 3 6 13 0 2 // ----------------------------------------------------------------------------- -// Memory attribute / context / control registers +// Identification -- read-only feature bitmaps // ----------------------------------------------------------------------------- -CONTEXTIDR_EL1 :: i64(0x4681) // 3 0 13 0 1 -CPACR_EL1 :: i64(0x4082) // 3 0 1 0 2 -MAIR_EL1 :: i64(0x4510) // 3 0 10 2 0 -AMAIR_EL1 :: i64(0x4518) // 3 0 10 3 0 -VTCR_EL2 :: i64(0x610A) // 3 4 2 1 2 -VTTBR_EL2 :: i64(0x6108) // 3 4 2 1 0 -ACTLR_EL1 :: i64(0x4081) // 3 0 1 0 1 -AFSR0_EL1 :: i64(0x4288) // 3 0 5 1 0 -AFSR1_EL1 :: i64(0x4289) // 3 0 5 1 1 -ISR_EL1 :: i64(0x4608) // 3 0 12 1 0 + +// op0 op1 CRn CRm op2 +CCSIDR_EL1 :: System_Register(0x4800) // 3 1 0 0 0 +CLIDR_EL1 :: System_Register(0x4801) // 3 1 0 0 1 +CSSELR_EL1 :: System_Register(0x5000) // 3 2 0 0 0 +CTR_EL0 :: System_Register(0x5801) // 3 3 0 0 1 +DCZID_EL0 :: System_Register(0x5807) // 3 3 0 0 7 (used by __sve_max_vl-style probes too) +GMID_EL1 :: System_Register(0x4804) // 3 1 0 0 4 (FEAT_MTE) +ID_AA64AFR0_EL1 :: System_Register(0x402C) // 3 0 0 5 4 (auxiliary) +ID_AA64AFR1_EL1 :: System_Register(0x402D) // 3 0 0 5 5 +ID_AA64DFR0_EL1 :: System_Register(0x4028) // 3 0 0 5 0 +ID_AA64DFR1_EL1 :: System_Register(0x4029) // 3 0 0 5 1 +ID_AA64DFR2_EL1 :: System_Register(0x402A) // 3 0 0 5 2 +ID_AA64ISAR0_EL1 :: System_Register(0x4030) // 3 0 0 6 0 +ID_AA64ISAR1_EL1 :: System_Register(0x4031) // 3 0 0 6 1 +ID_AA64ISAR2_EL1 :: System_Register(0x4032) // 3 0 0 6 2 +ID_AA64ISAR3_EL1 :: System_Register(0x4033) // 3 0 0 6 3 +ID_AA64MMFR0_EL1 :: System_Register(0x4038) // 3 0 0 7 0 +ID_AA64MMFR1_EL1 :: System_Register(0x4039) // 3 0 0 7 1 +ID_AA64MMFR2_EL1 :: System_Register(0x403A) // 3 0 0 7 2 +ID_AA64PFR0_EL1 :: System_Register(0x4020) // 3 0 0 4 0 +ID_AA64PFR1_EL1 :: System_Register(0x4021) // 3 0 0 4 1 +ID_AA64SMFR0_EL1 :: System_Register(0x4025) // 3 0 0 4 5 (SME feature ID) +ID_AA64ZFR0_EL1 :: System_Register(0x4024) // 3 0 0 4 4 (SVE feature ID) +ID_AFR0_EL1 :: System_Register(0x400B) // 3 0 0 1 3 +ID_DFR0_EL1 :: System_Register(0x400A) // 3 0 0 1 2 +ID_ISAR0_EL1 :: System_Register(0x4010) // 3 0 0 2 0 +ID_ISAR1_EL1 :: System_Register(0x4011) // 3 0 0 2 1 +ID_ISAR2_EL1 :: System_Register(0x4012) // 3 0 0 2 2 +ID_ISAR3_EL1 :: System_Register(0x4013) // 3 0 0 2 3 +ID_ISAR4_EL1 :: System_Register(0x4014) // 3 0 0 2 4 +ID_ISAR5_EL1 :: System_Register(0x4015) // 3 0 0 2 5 +ID_ISAR6_EL1 :: System_Register(0x4017) // 3 0 0 2 7 +ID_MMFR0_EL1 :: System_Register(0x400C) // 3 0 0 1 4 +ID_MMFR1_EL1 :: System_Register(0x400D) // 3 0 0 1 5 +ID_MMFR2_EL1 :: System_Register(0x400E) // 3 0 0 1 6 +ID_MMFR3_EL1 :: System_Register(0x400F) // 3 0 0 1 7 +ID_MMFR4_EL1 :: System_Register(0x4016) // 3 0 0 2 6 +ID_MMFR5_EL1 :: System_Register(0x401E) // 3 0 0 3 6 +ID_PFR0_EL1 :: System_Register(0x4008) // 3 0 0 1 0 +ID_PFR1_EL1 :: System_Register(0x4009) // 3 0 0 1 1 +ID_PFR2_EL1 :: System_Register(0x401C) // 3 0 0 3 4 +MIDR_EL1 :: System_Register(0x4000) // 3 0 0 0 0 +MPIDR_EL1 :: System_Register(0x4005) // 3 0 0 0 5 // ----------------------------------------------------------------------------- -// Random number registers (v8.5-A FEAT_RNG) +// Pointer authentication keys (FEAT_PAuth) // ----------------------------------------------------------------------------- -RNDR :: i64(0x5920) // 3 3 2 4 0 -RNDRRS :: i64(0x5921) // 3 3 2 4 1 + +// op0 op1 CRn CRm op2 +APDAKEYHI_EL1 :: System_Register(0x4111) // 3 0 2 2 1 +APDAKEYLO_EL1 :: System_Register(0x4110) // 3 0 2 2 0 +APDBKEYHI_EL1 :: System_Register(0x4113) // 3 0 2 2 3 +APDBKEYLO_EL1 :: System_Register(0x4112) // 3 0 2 2 2 +APGAKEYHI_EL1 :: System_Register(0x4119) // 3 0 2 3 1 +APGAKEYLO_EL1 :: System_Register(0x4118) // 3 0 2 3 0 +APIAKEYHI_EL1 :: System_Register(0x4109) // 3 0 2 1 1 +APIAKEYLO_EL1 :: System_Register(0x4108) // 3 0 2 1 0 (FEAT_PAuth) +APIBKEYHI_EL1 :: System_Register(0x410B) // 3 0 2 1 3 +APIBKEYLO_EL1 :: System_Register(0x410A) // 3 0 2 1 2 // ----------------------------------------------------------------------------- -// More ID registers +// Memory tagging (FEAT_MTE) // ----------------------------------------------------------------------------- -ID_AA64ZFR0_EL1 :: i64(0x4024) // 3 0 0 4 4 (SVE feature ID) -ID_AA64SMFR0_EL1 :: i64(0x4025) // 3 0 0 4 5 (SME feature ID) -ID_AA64AFR0_EL1 :: i64(0x402C) // 3 0 0 5 4 (auxiliary) -ID_AA64AFR1_EL1 :: i64(0x402D) // 3 0 0 5 5 + +// op0 op1 CRn CRm op2 +GCR_EL1 :: System_Register(0x4086) // 3 0 1 0 6 (FEAT_MTE) +RGSR_EL1 :: System_Register(0x4085) // 3 0 1 0 5 (FEAT_MTE) +TFSRE0_EL1 :: System_Register(0x42B1) // 3 0 5 6 1 (FEAT_MTE) +TFSR_EL1 :: System_Register(0x42B0) // 3 0 5 6 0 (FEAT_MTE) // ----------------------------------------------------------------------------- -// Cache hierarchy + selection +// SVE and SME configuration // ----------------------------------------------------------------------------- -CCSIDR_EL1 :: i64(0x4800) // 3 1 0 0 0 -CLIDR_EL1 :: i64(0x4801) // 3 1 0 0 1 -CSSELR_EL1 :: i64(0x5000) // 3 2 0 0 0 + +// op0 op1 CRn CRm op2 +SMCR_EL1 :: System_Register(0x4096) // 3 0 1 2 6 (FEAT_SME) +SMCR_EL2 :: System_Register(0x6096) // 3 4 1 2 6 +SVCR :: System_Register(0x5A12) // 3 3 4 2 2 (FEAT_SME: SM + ZA bits) +ZCR_EL1 :: System_Register(0x4090) // 3 0 1 2 0 (FEAT_SVE) +ZCR_EL2 :: System_Register(0x6090) // 3 4 1 2 0 +ZCR_EL3 :: System_Register(0x7090) // 3 6 1 2 0 // ----------------------------------------------------------------------------- -// EL2 / EL3 control + return registers +// System control and memory management // ----------------------------------------------------------------------------- -SCTLR_EL2 :: i64(0x6080) // 3 4 1 0 0 -SCTLR_EL3 :: i64(0x7080) // 3 6 1 0 0 -SPSR_EL3 :: i64(0x7200) // 3 6 4 0 0 -ELR_EL3 :: i64(0x7201) // 3 6 4 0 1 -TPIDR_EL2 :: i64(0x6682) // 3 4 13 0 2 -TPIDR_EL3 :: i64(0x7682) // 3 6 13 0 2 -- err, EL3 needs op1=6 -HSTR_EL2 :: i64(0x608B) // 3 4 1 1 3 -MDCR_EL2 :: i64(0x6089) // 3 4 1 1 1 -CNTHCTL_EL2 :: i64(0x6708) // 3 4 14 1 0 -DACR32_EL2 :: i64(0x6180) // 3 4 3 0 0 -FPEXC32_EL2 :: i64(0x6298) // 3 4 5 3 0 -VBAR_EL2 :: i64(0x6600) // 3 4 12 0 0 -VBAR_EL3 :: i64(0x7600) // 3 6 12 0 0 -TPIDR2_EL0 :: i64(0x5E85) // 3 3 13 0 5 (SME thread pointer 2) + +// op0 op1 CRn CRm op2 +ACTLR_EL1 :: System_Register(0x4081) // 3 0 1 0 1 +AMAIR_EL1 :: System_Register(0x4518) // 3 0 10 3 0 +CPACR_EL1 :: System_Register(0x4082) // 3 0 1 0 2 +LORC_EL1 :: System_Register(0x4523) // 3 0 10 4 3 +LOREA_EL1 :: System_Register(0x4521) // 3 0 10 4 1 +LORID_EL1 :: System_Register(0x4527) // 3 0 10 4 7 +LORN_EL1 :: System_Register(0x4522) // 3 0 10 4 2 +LORSA_EL1 :: System_Register(0x4520) // 3 0 10 4 0 +MAIR_EL1 :: System_Register(0x4510) // 3 0 10 2 0 +PAR_EL1 :: System_Register(0x43A0) // 3 0 7 4 0 +SCTLR_EL1 :: System_Register(0x4080) // 3 0 1 0 0 +SCTLR_EL2 :: System_Register(0x6080) // 3 4 1 0 0 +SCTLR_EL3 :: System_Register(0x7080) // 3 6 1 0 0 +TCR_EL1 :: System_Register(0x4102) // 3 0 2 0 2 +TTBR0_EL1 :: System_Register(0x4100) // 3 0 2 0 0 +TTBR1_EL1 :: System_Register(0x4101) // 3 0 2 0 1 // ----------------------------------------------------------------------------- -// Debug registers (op0 = 2) +// Generic timer // ----------------------------------------------------------------------------- -MDSCR_EL1 :: i64(0x0012) // 2 0 0 2 2 -DSPSR_EL0 :: i64(0x5A28) // 3 3 4 5 0 -DLR_EL0 :: i64(0x5A29) // 3 3 4 5 1 -OSLAR_EL1 :: i64(0x0084) // 2 0 1 0 4 (op0=2 -> o0=0) -OSLSR_EL1 :: i64(0x008C) // 2 0 1 1 4 + +// op0 op1 CRn CRm op2 +CNTFRQ_EL0 :: System_Register(0x5F00) // 3 3 14 0 0 +CNTHCTL_EL2 :: System_Register(0x6708) // 3 4 14 1 0 +CNTHP_CTL_EL2 :: System_Register(0x6711) // 3 4 14 2 1 +CNTHP_CVAL_EL2 :: System_Register(0x6712) // 3 4 14 2 2 +CNTHP_TVAL_EL2 :: System_Register(0x6710) // 3 4 14 2 0 +CNTHV_CTL_EL2 :: System_Register(0x6719) // 3 4 14 3 1 +CNTHV_CVAL_EL2 :: System_Register(0x671A) // 3 4 14 3 2 +CNTHV_TVAL_EL2 :: System_Register(0x6718) // 3 4 14 3 0 +CNTKCTL_EL1 :: System_Register(0x4708) // 3 0 14 1 0 +CNTPCT_EL0 :: System_Register(0x5F01) // 3 3 14 0 1 +CNTPS_CTL_EL1 :: System_Register(0x7F11) // 3 7 14 2 1 +CNTPS_CVAL_EL1 :: System_Register(0x7F12) // 3 7 14 2 2 +CNTPS_TVAL_EL1 :: System_Register(0x7F10) // 3 7 14 2 0 +CNTP_CTL_EL0 :: System_Register(0x5F11) // 3 3 14 2 1 +CNTP_CVAL_EL0 :: System_Register(0x5F12) // 3 3 14 2 2 +CNTP_TVAL_EL0 :: System_Register(0x5F10) // 3 3 14 2 0 +CNTVCT_EL0 :: System_Register(0x5F02) // 3 3 14 0 2 +CNTVOFF_EL2 :: System_Register(0x6703) // 3 4 14 0 3 +CNTV_CTL_EL0 :: System_Register(0x5F19) // 3 3 14 3 1 +CNTV_CVAL_EL0 :: System_Register(0x5F1A) // 3 3 14 3 2 +CNTV_TVAL_EL0 :: System_Register(0x5F18) // 3 3 14 3 0 // ----------------------------------------------------------------------------- -// Cache / Memory feature extras +// Statistical profiling (FEAT_SPE) // ----------------------------------------------------------------------------- -RGSR_EL1 :: i64(0x4085) // 3 0 1 0 5 (FEAT_MTE) -GCR_EL1 :: i64(0x4086) // 3 0 1 0 6 (FEAT_MTE) -TFSR_EL1 :: i64(0x42B0) // 3 0 5 6 0 (FEAT_MTE) -TFSRE0_EL1 :: i64(0x42B1) // 3 0 5 6 1 (FEAT_MTE) -GMID_EL1 :: i64(0x4804) // 3 1 0 0 4 (FEAT_MTE) + +// op0 op1 CRn CRm op2 +PMBIDR_EL1 :: System_Register(0x44D7) // 3 0 9 10 7 +PMBLIMITR_EL1 :: System_Register(0x44D0) // 3 0 9 10 0 +PMBPTR_EL1 :: System_Register(0x44D1) // 3 0 9 10 1 +PMBSR_EL1 :: System_Register(0x44D3) // 3 0 9 10 3 +PMSCR_EL1 :: System_Register(0x44C8) // 3 0 9 9 0 +PMSELR_EL0 :: System_Register(0x5CE5) // 3 3 9 12 5 +PMSEVFR_EL1 :: System_Register(0x44CD) // 3 0 9 9 5 +PMSFCR_EL1 :: System_Register(0x44CC) // 3 0 9 9 4 +PMSICR_EL1 :: System_Register(0x44CA) // 3 0 9 9 2 +PMSIDR_EL1 :: System_Register(0x44CF) // 3 0 9 9 7 +PMSIRR_EL1 :: System_Register(0x44CB) // 3 0 9 9 3 +PMSLATFR_EL1 :: System_Register(0x44CE) // 3 0 9 9 6 +PMSWINC_EL0 :: System_Register(0x5CE4) // 3 3 9 12 4 // ----------------------------------------------------------------------------- -// SME / SVE configuration +// Performance monitors // ----------------------------------------------------------------------------- -SVCR :: i64(0x5A12) // 3 3 4 2 2 (FEAT_SME: SM + ZA bits) -SMCR_EL1 :: i64(0x4096) // 3 0 1 2 6 (FEAT_SME) -SMCR_EL2 :: i64(0x6096) // 3 4 1 2 6 -ZCR_EL1 :: i64(0x4090) // 3 0 1 2 0 (FEAT_SVE) -ZCR_EL2 :: i64(0x6090) // 3 4 1 2 0 -ZCR_EL3 :: i64(0x7090) // 3 6 1 2 0 + +// op0 op1 CRn CRm op2 +PMCCFILTR_EL0 :: System_Register(0x5F7F) // 3 3 14 15 7 +PMCCNTR_EL0 :: System_Register(0x5CE8) // 3 3 9 13 0 +PMCEID0_EL0 :: System_Register(0x5CE6) // 3 3 9 12 6 +PMCEID1_EL0 :: System_Register(0x5CE7) // 3 3 9 12 7 +PMCNTENCLR_EL0 :: System_Register(0x5CE2) // 3 3 9 12 2 +PMCNTENSET_EL0 :: System_Register(0x5CE1) // 3 3 9 12 1 +PMCR_EL0 :: System_Register(0x5CE0) // 3 3 9 12 0 +PMINTENCLR_EL1 :: System_Register(0x44F2) // 3 0 9 14 2 +PMINTENSET_EL1 :: System_Register(0x44F1) // 3 0 9 14 1 +PMOVSCLR_EL0 :: System_Register(0x5CE3) // 3 3 9 12 3 +PMUSERENR_EL0 :: System_Register(0x5CF0) // 3 3 9 14 0 // ----------------------------------------------------------------------------- -// Cache / data prefetch hint controls +// Trace // ----------------------------------------------------------------------------- -PRSELR_EL1 :: i64(0x4311) // 3 0 6 2 1 -APIAKEYLO_EL1 :: i64(0x4108) // 3 0 2 1 0 (FEAT_PAuth) -APIAKEYHI_EL1 :: i64(0x4109) // 3 0 2 1 1 -APIBKEYLO_EL1 :: i64(0x410A) // 3 0 2 1 2 -APIBKEYHI_EL1 :: i64(0x410B) // 3 0 2 1 3 -APDAKEYLO_EL1 :: i64(0x4110) // 3 0 2 2 0 -APDAKEYHI_EL1 :: i64(0x4111) // 3 0 2 2 1 -APDBKEYLO_EL1 :: i64(0x4112) // 3 0 2 2 2 -APDBKEYHI_EL1 :: i64(0x4113) // 3 0 2 2 3 -APGAKEYLO_EL1 :: i64(0x4118) // 3 0 2 3 0 -APGAKEYHI_EL1 :: i64(0x4119) // 3 0 2 3 1 -// ============================================================================= -// Batch 5: comprehensive sysreg sweep -// ============================================================================= +// op0 op1 CRn CRm op2 +TRBBASER_EL1 :: System_Register(0x44DA) // 3 0 9 11 2 +TRBIDR_EL1 :: System_Register(0x44DF) // 3 0 9 11 7 +TRBLIMITR_EL1 :: System_Register(0x44D8) // 3 0 9 11 0 +TRBMAR_EL1 :: System_Register(0x44DC) // 3 0 9 11 4 +TRBPTR_EL1 :: System_Register(0x44D9) // 3 0 9 11 1 +TRBSR_EL1 :: System_Register(0x44DB) // 3 0 9 11 3 +TRBTRG_EL1 :: System_Register(0x44DE) // 3 0 9 11 6 -// ---- More ID registers (AArch32 + extras) ---- -ID_AA64DFR2_EL1 :: i64(0x402A) // 3 0 0 5 2 -ID_AA64ISAR3_EL1 :: i64(0x4033) // 3 0 0 6 3 -ID_PFR0_EL1 :: i64(0x4008) // 3 0 0 1 0 -ID_PFR1_EL1 :: i64(0x4009) // 3 0 0 1 1 -ID_DFR0_EL1 :: i64(0x400A) // 3 0 0 1 2 -ID_AFR0_EL1 :: i64(0x400B) // 3 0 0 1 3 -ID_MMFR0_EL1 :: i64(0x400C) // 3 0 0 1 4 -ID_MMFR1_EL1 :: i64(0x400D) // 3 0 0 1 5 -ID_MMFR2_EL1 :: i64(0x400E) // 3 0 0 1 6 -ID_MMFR3_EL1 :: i64(0x400F) // 3 0 0 1 7 -ID_MMFR4_EL1 :: i64(0x4016) // 3 0 0 2 6 -ID_MMFR5_EL1 :: i64(0x401E) // 3 0 0 3 6 -ID_ISAR0_EL1 :: i64(0x4010) // 3 0 0 2 0 -ID_ISAR1_EL1 :: i64(0x4011) // 3 0 0 2 1 -ID_ISAR2_EL1 :: i64(0x4012) // 3 0 0 2 2 -ID_ISAR3_EL1 :: i64(0x4013) // 3 0 0 2 3 -ID_ISAR4_EL1 :: i64(0x4014) // 3 0 0 2 4 -ID_ISAR5_EL1 :: i64(0x4015) // 3 0 0 2 5 -ID_ISAR6_EL1 :: i64(0x4017) // 3 0 0 2 7 -ID_PFR2_EL1 :: i64(0x401C) // 3 0 0 3 4 -MVFR0_EL1 :: i64(0x4018) // 3 0 0 3 0 -MVFR1_EL1 :: i64(0x4019) // 3 0 0 3 1 -MVFR2_EL1 :: i64(0x401A) // 3 0 0 3 2 +// ----------------------------------------------------------------------------- +// Debug +// ----------------------------------------------------------------------------- -// ---- Counter / Timer (full set) ---- -CNTKCTL_EL1 :: i64(0x4708) // 3 0 14 1 0 -CNTP_TVAL_EL0 :: i64(0x5F10) // 3 3 14 2 0 -CNTP_CTL_EL0 :: i64(0x5F11) // 3 3 14 2 1 -CNTP_CVAL_EL0 :: i64(0x5F12) // 3 3 14 2 2 -CNTV_TVAL_EL0 :: i64(0x5F18) // 3 3 14 3 0 -CNTV_CTL_EL0 :: i64(0x5F19) // 3 3 14 3 1 -CNTV_CVAL_EL0 :: i64(0x5F1A) // 3 3 14 3 2 -CNTHP_TVAL_EL2 :: i64(0x6710) // 3 4 14 2 0 -CNTHP_CTL_EL2 :: i64(0x6711) // 3 4 14 2 1 -CNTHP_CVAL_EL2 :: i64(0x6712) // 3 4 14 2 2 -CNTHV_TVAL_EL2 :: i64(0x6718) // 3 4 14 3 0 -CNTHV_CTL_EL2 :: i64(0x6719) // 3 4 14 3 1 -CNTHV_CVAL_EL2 :: i64(0x671A) // 3 4 14 3 2 -CNTPS_TVAL_EL1 :: i64(0x7F10) // 3 7 14 2 0 -CNTPS_CTL_EL1 :: i64(0x7F11) // 3 7 14 2 1 -CNTPS_CVAL_EL1 :: i64(0x7F12) // 3 7 14 2 2 -CNTVOFF_EL2 :: i64(0x6703) // 3 4 14 0 3 +// op0 op1 CRn CRm op2 +DBGAUTHSTATUS_EL1 :: System_Register(0x03F6) // 2 0 7 14 6 +DBGCLAIMCLR_EL1 :: System_Register(0x03CE) // 2 0 7 9 6 +DBGCLAIMSET_EL1 :: System_Register(0x03C6) // 2 0 7 8 6 +DBGDTRRX_EL0 :: System_Register(0x1828) // 2 3 0 5 0 +DBGDTRTX_EL0 :: System_Register(0x1828) // 2 3 0 5 0 (write view of DBGDTRRX_EL0) +DBGDTR_EL0 :: System_Register(0x1820) // 2 3 0 4 0 +DBGPRCR_EL1 :: System_Register(0x00A4) // 2 0 1 4 4 +DLR_EL0 :: System_Register(0x5A29) // 3 3 4 5 1 +DSPSR_EL0 :: System_Register(0x5A28) // 3 3 4 5 0 +MDCCINT_EL1 :: System_Register(0x0010) // 2 0 0 2 0 +MDRAR_EL1 :: System_Register(0x0080) // 2 0 1 0 0 +MDSCR_EL1 :: System_Register(0x0012) // 2 0 0 2 2 +OSLAR_EL1 :: System_Register(0x0084) // 2 0 1 0 4 (op0=2 -> o0=0) +OSLSR_EL1 :: System_Register(0x008C) // 2 0 1 1 4 +PRSELR_EL1 :: System_Register(0x4311) // 3 0 6 2 1 -// ---- Debug breakpoints (DBGB*) and watchpoints (DBGW*), numbered ---- -// -// Each register file is 16 deep: DBGBVR0..15, DBGBCR0..15, DBGWVR0..15, -// DBGWCR0..15. Use the helper: -// sysreg_debug_breakpoint_value(n) -- DBGBVRn_EL1 = (2, 0, 0, n, 4) -// sysreg_debug_breakpoint_control(n) -- DBGBCRn_EL1 = (2, 0, 0, n, 5) -// sysreg_debug_watchpoint_value(n) -- DBGWVRn_EL1 = (2, 0, 0, n, 6) -// sysreg_debug_watchpoint_control(n) -- DBGWCRn_EL1 = (2, 0, 0, n, 7) +// ----------------------------------------------------------------------------- +// Generic interrupt controller +// ----------------------------------------------------------------------------- -sysreg_debug_breakpoint_value :: #force_inline proc "contextless" (n: u32) -> i64 { - return sysreg_field(2, 0, 0, n & 0xF, 4) -} -sysreg_debug_breakpoint_control :: #force_inline proc "contextless" (n: u32) -> i64 { - return sysreg_field(2, 0, 0, n & 0xF, 5) -} -sysreg_debug_watchpoint_value :: #force_inline proc "contextless" (n: u32) -> i64 { - return sysreg_field(2, 0, 0, n & 0xF, 6) -} -sysreg_debug_watchpoint_control :: #force_inline proc "contextless" (n: u32) -> i64 { - return sysreg_field(2, 0, 0, n & 0xF, 7) -} +// op0 op1 CRn CRm op2 +ICC_ASGI1R_EL1 :: System_Register(0x465E) // 3 0 12 11 6 +ICC_BPR0_EL1 :: System_Register(0x4643) // 3 0 12 8 3 +ICC_BPR1_EL1 :: System_Register(0x4663) // 3 0 12 12 3 +ICC_CTLR_EL1 :: System_Register(0x4664) // 3 0 12 12 4 +ICC_CTLR_EL3 :: System_Register(0x7664) // 3 6 12 12 4 +ICC_DIR_EL1 :: System_Register(0x4659) // 3 0 12 11 1 +ICC_EOIR0_EL1 :: System_Register(0x4641) // 3 0 12 8 1 +ICC_EOIR1_EL1 :: System_Register(0x4661) // 3 0 12 12 1 +ICC_HPPIR0_EL1 :: System_Register(0x4642) // 3 0 12 8 2 +ICC_HPPIR1_EL1 :: System_Register(0x4662) // 3 0 12 12 2 +ICC_IAR0_EL1 :: System_Register(0x4640) // 3 0 12 8 0 +ICC_IAR1_EL1 :: System_Register(0x4660) // 3 0 12 12 0 +ICC_IGRPEN0_EL1 :: System_Register(0x4666) // 3 0 12 12 6 +ICC_IGRPEN1_EL1 :: System_Register(0x4667) // 3 0 12 12 7 +ICC_IGRPEN1_EL3 :: System_Register(0x7667) // 3 6 12 12 7 +ICC_PMR_EL1 :: System_Register(0x4230) // 3 0 4 6 0 +ICC_RPR_EL1 :: System_Register(0x465B) // 3 0 12 11 3 +ICC_SGI0R_EL1 :: System_Register(0x465F) // 3 0 12 11 7 +ICC_SGI1R_EL1 :: System_Register(0x465D) // 3 0 12 11 5 +ICC_SRE_EL1 :: System_Register(0x4665) // 3 0 12 12 5 +ICC_SRE_EL2 :: System_Register(0x664D) // 3 4 12 9 5 +ICC_SRE_EL3 :: System_Register(0x7665) // 3 6 12 12 5 +ICH_EISR_EL2 :: System_Register(0x665B) // 3 4 12 11 3 +ICH_ELRSR_EL2 :: System_Register(0x665D) // 3 4 12 11 5 +ICH_HCR_EL2 :: System_Register(0x6658) // 3 4 12 11 0 +ICH_MISR_EL2 :: System_Register(0x665A) // 3 4 12 11 2 +ICH_VMCR_EL2 :: System_Register(0x665F) // 3 4 12 11 7 +ICH_VTR_EL2 :: System_Register(0x6659) // 3 4 12 11 1 -// Other debug registers -DBGDTR_EL0 :: i64(0x1820) // 2 3 0 4 0 -DBGDTRRX_EL0 :: i64(0x1828) // 2 3 0 5 0 -DBGDTRTX_EL0 :: i64(0x1828) // 2 3 0 5 0 (write view of DBGDTRRX_EL0) -DBGPRCR_EL1 :: i64(0x00A4) // 2 0 1 4 4 -DBGCLAIMSET_EL1 :: i64(0x03C6) // 2 0 7 8 6 -DBGCLAIMCLR_EL1 :: i64(0x03CE) // 2 0 7 9 6 -DBGAUTHSTATUS_EL1:: i64(0x03F6) // 2 0 7 14 6 -MDCCINT_EL1 :: i64(0x0010) // 2 0 0 2 0 -MDRAR_EL1 :: i64(0x0080) // 2 0 1 0 0 +// ----------------------------------------------------------------------------- +// RAS -- error record registers +// ----------------------------------------------------------------------------- -// PMU event counters (PMEVCNTRn_EL0 / PMEVTYPERn_EL0). Up to n=30. -// PMEVCNTRn_EL0 = sysreg(3, 3, 14, 8+(n>>3), n & 7) -// PMEVTYPERn_EL0 = sysreg(3, 3, 14, 12+(n>>3), n & 7) +// op0 op1 CRn CRm op2 +DISR_EL1 :: System_Register(0x4609) // 3 0 12 1 1 +ERRIDR_EL1 :: System_Register(0x4298) // 3 0 5 3 0 +ERRSELR_EL1 :: System_Register(0x4299) // 3 0 5 3 1 +ERXADDR_EL1 :: System_Register(0x42A3) // 3 0 5 4 3 +ERXCTLR_EL1 :: System_Register(0x42A1) // 3 0 5 4 1 +ERXFR_EL1 :: System_Register(0x42A0) // 3 0 5 4 0 +ERXMISC0_EL1 :: System_Register(0x42A8) // 3 0 5 5 0 +ERXMISC1_EL1 :: System_Register(0x42A9) // 3 0 5 5 1 +ERXMISC2_EL1 :: System_Register(0x42AA) // 3 0 5 5 2 +ERXMISC3_EL1 :: System_Register(0x42AB) // 3 0 5 5 3 +ERXSTATUS_EL1 :: System_Register(0x42A2) // 3 0 5 4 2 +VDISR_EL2 :: System_Register(0x6609) // 3 4 12 1 1 +VSESR_EL2 :: System_Register(0x6293) // 3 4 5 2 3 -sysreg_pmu_event_counter :: #force_inline proc "contextless" (n: u32) -> i64 { - return sysreg_field(3, 3, 14, 8 + ((n >> 3) & 0x3), n & 0x7) -} -sysreg_pmu_event_typer :: #force_inline proc "contextless" (n: u32) -> i64 { - return sysreg_field(3, 3, 14, 12 + ((n >> 3) & 0x3), n & 0x7) -} +// ----------------------------------------------------------------------------- +// Virtualisation (EL2) and secure monitor (EL3) +// ----------------------------------------------------------------------------- -PMINTENSET_EL1 :: i64(0x44F1) // 3 0 9 14 1 -PMINTENCLR_EL1 :: i64(0x44F2) // 3 0 9 14 2 +// op0 op1 CRn CRm op2 +GPCCR_EL3 :: System_Register(0x710E) // 3 6 2 1 6 (Granule Protection Control) +GPTBR_EL3 :: System_Register(0x710C) // 3 6 2 1 4 (Granule Protection Table Base) +HCR_EL2 :: System_Register(0x6088) // 3 4 1 1 0 +HSTR_EL2 :: System_Register(0x608B) // 3 4 1 1 3 +MDCR_EL2 :: System_Register(0x6089) // 3 4 1 1 1 +MFAR_EL3 :: System_Register(0x7305) // 3 6 6 0 5 (Multiple FAR) +VTCR_EL2 :: System_Register(0x610A) // 3 4 2 1 2 +VTTBR_EL2 :: System_Register(0x6108) // 3 4 2 1 0 -// ---- GICv3 (ICC_*) -- CPU interface ---- -ICC_IAR0_EL1 :: i64(0x4640) // 3 0 12 8 0 -ICC_IAR1_EL1 :: i64(0x4660) // 3 0 12 12 0 -ICC_EOIR0_EL1 :: i64(0x4641) // 3 0 12 8 1 -ICC_EOIR1_EL1 :: i64(0x4661) // 3 0 12 12 1 -ICC_HPPIR0_EL1 :: i64(0x4642) // 3 0 12 8 2 -ICC_HPPIR1_EL1 :: i64(0x4662) // 3 0 12 12 2 -ICC_BPR0_EL1 :: i64(0x4643) // 3 0 12 8 3 -ICC_BPR1_EL1 :: i64(0x4663) // 3 0 12 12 3 -ICC_DIR_EL1 :: i64(0x4659) // 3 0 12 11 1 -ICC_PMR_EL1 :: i64(0x4230) // 3 0 4 6 0 -ICC_RPR_EL1 :: i64(0x465B) // 3 0 12 11 3 -ICC_SGI0R_EL1 :: i64(0x465F) // 3 0 12 11 7 -ICC_SGI1R_EL1 :: i64(0x465D) // 3 0 12 11 5 -ICC_ASGI1R_EL1 :: i64(0x465E) // 3 0 12 11 6 -ICC_SRE_EL1 :: i64(0x4665) // 3 0 12 12 5 -ICC_SRE_EL2 :: i64(0x664D) // 3 4 12 9 5 -ICC_SRE_EL3 :: i64(0x7665) // 3 6 12 12 5 -ICC_CTLR_EL1 :: i64(0x4664) // 3 0 12 12 4 -ICC_CTLR_EL3 :: i64(0x7664) // 3 6 12 12 4 -ICC_IGRPEN0_EL1 :: i64(0x4666) // 3 0 12 12 6 -ICC_IGRPEN1_EL1 :: i64(0x4667) // 3 0 12 12 7 -ICC_IGRPEN1_EL3 :: i64(0x7667) // 3 6 12 12 7 +// ----------------------------------------------------------------------------- +// AArch32 compatibility +// ----------------------------------------------------------------------------- -// ---- GICv3 hypervisor (ICH_*) ---- -ICH_HCR_EL2 :: i64(0x6658) // 3 4 12 11 0 -ICH_VTR_EL2 :: i64(0x6659) // 3 4 12 11 1 -ICH_MISR_EL2 :: i64(0x665A) // 3 4 12 11 2 -ICH_EISR_EL2 :: i64(0x665B) // 3 4 12 11 3 -ICH_ELRSR_EL2 :: i64(0x665D) // 3 4 12 11 5 -ICH_VMCR_EL2 :: i64(0x665F) // 3 4 12 11 7 +// op0 op1 CRn CRm op2 +DACR32_EL2 :: System_Register(0x6180) // 3 4 3 0 0 +FPEXC32_EL2 :: System_Register(0x6298) // 3 4 5 3 0 -// ICH_LR0_EL2 .. ICH_LR15_EL2 = sysreg(3, 4, 12, 12+(n>>3), n & 7) -sysreg_ich_lr :: #force_inline proc "contextless" (n: u32) -> i64 { - return sysreg_field(3, 4, 12, 12 + ((n >> 3) & 0x1), n & 0x7) -} +// ----------------------------------------------------------------------------- +// Random number (FEAT_RNG) +// ----------------------------------------------------------------------------- -// ICH_AP0Rn_EL2 (n=0..3) and ICH_AP1Rn_EL2 (n=0..3) -sysreg_ich_ap0r :: #force_inline proc "contextless" (n: u32) -> i64 { - return sysreg_field(3, 4, 12, 8, n & 0x3) -} -sysreg_ich_ap1r :: #force_inline proc "contextless" (n: u32) -> i64 { - return sysreg_field(3, 4, 12, 9, n & 0x3) -} - -// ---- TRBE (Trace Buffer Extension, FEAT_TRBE) ---- -TRBLIMITR_EL1 :: i64(0x44D8) // 3 0 9 11 0 -TRBPTR_EL1 :: i64(0x44D9) // 3 0 9 11 1 -TRBBASER_EL1 :: i64(0x44DA) // 3 0 9 11 2 -TRBSR_EL1 :: i64(0x44DB) // 3 0 9 11 3 -TRBMAR_EL1 :: i64(0x44DC) // 3 0 9 11 4 -TRBTRG_EL1 :: i64(0x44DE) // 3 0 9 11 6 -TRBIDR_EL1 :: i64(0x44DF) // 3 0 9 11 7 - -// ---- SPE (Statistical Profiling Extension, FEAT_SPE) ---- -PMSCR_EL1 :: i64(0x44C8) // 3 0 9 9 0 -PMSICR_EL1 :: i64(0x44CA) // 3 0 9 9 2 -PMSIRR_EL1 :: i64(0x44CB) // 3 0 9 9 3 -PMSFCR_EL1 :: i64(0x44CC) // 3 0 9 9 4 -PMSEVFR_EL1 :: i64(0x44CD) // 3 0 9 9 5 -PMSLATFR_EL1 :: i64(0x44CE) // 3 0 9 9 6 -PMSIDR_EL1 :: i64(0x44CF) // 3 0 9 9 7 -PMBLIMITR_EL1 :: i64(0x44D0) // 3 0 9 10 0 -PMBPTR_EL1 :: i64(0x44D1) // 3 0 9 10 1 -PMBSR_EL1 :: i64(0x44D3) // 3 0 9 10 3 -PMBIDR_EL1 :: i64(0x44D7) // 3 0 9 10 7 - -// ---- RAS (Reliability, Availability, Serviceability) ---- -ERRSELR_EL1 :: i64(0x4299) // 3 0 5 3 1 -ERRIDR_EL1 :: i64(0x4298) // 3 0 5 3 0 -ERXADDR_EL1 :: i64(0x42A3) // 3 0 5 4 3 -ERXCTLR_EL1 :: i64(0x42A1) // 3 0 5 4 1 -ERXFR_EL1 :: i64(0x42A0) // 3 0 5 4 0 -ERXSTATUS_EL1 :: i64(0x42A2) // 3 0 5 4 2 -ERXMISC0_EL1 :: i64(0x42A8) // 3 0 5 5 0 -ERXMISC1_EL1 :: i64(0x42A9) // 3 0 5 5 1 -ERXMISC2_EL1 :: i64(0x42AA) // 3 0 5 5 2 -ERXMISC3_EL1 :: i64(0x42AB) // 3 0 5 5 3 -DISR_EL1 :: i64(0x4609) // 3 0 12 1 1 -VDISR_EL2 :: i64(0x6609) // 3 4 12 1 1 -VSESR_EL2 :: i64(0x6293) // 3 4 5 2 3 - -// ---- LOR (Limited Ordering Region) ---- -LORC_EL1 :: i64(0x4523) // 3 0 10 4 3 -LOREA_EL1 :: i64(0x4521) // 3 0 10 4 1 -LORID_EL1 :: i64(0x4527) // 3 0 10 4 7 -LORN_EL1 :: i64(0x4522) // 3 0 10 4 2 -LORSA_EL1 :: i64(0x4520) // 3 0 10 4 0 - -// ---- Translation result (returned by AT) ---- -PAR_EL1 :: i64(0x43A0) // 3 0 7 4 0 - -// ---- RME (Realm Management Extension) sysregs ---- -GPCCR_EL3 :: i64(0x710E) // 3 6 2 1 6 (Granule Protection Control) -GPTBR_EL3 :: i64(0x710C) // 3 6 2 1 4 (Granule Protection Table Base) -MFAR_EL3 :: i64(0x7305) // 3 6 6 0 5 (Multiple FAR) - -// ---- TPIDRRO_EL0 alias / extra thread pointers ---- -// (TPIDRRO_EL0 already added above) - -// ---- Performance Monitor extras ---- -PMCCFILTR_EL0 :: i64(0x5F7F) // 3 3 14 15 7 -PMUSERENR_EL0_REPEAT :: PMUSERENR_EL0 // re-export alias placeholder +// op0 op1 CRn CRm op2 +RNDR :: System_Register(0x5920) // 3 3 2 4 0 +RNDRRS :: System_Register(0x5921) // 3 3 2 4 1 // ----------------------------------------------------------------------------- // Value -> name, for printing // ----------------------------------------------------------------------------- // -// MRS/MSR carry the system register as a packed 15-bit field, so a disassembly -// has a number where an assembler wants a name. Sorted by value; binary search. +// A disassembly has the packed field where an assembler wants a name. Sorted +// by value; binary search. // -// 1 encodings carry two names. Where the pair is a read view and a write -// view of one register (DBGDTRRX/DBGDTRTX) the read name wins, since MRS is -// the direction that has to print; the rest are genuine aliases and either -// name assembles, so a round-trip can come back spelled as the sibling. +// 1 encoding carries two names: DBGDTRRX_EL0 and DBGDTRTX_EL0 are the read +// and write views of one register. The read name wins, since MRS is the +// direction that has to print. Sysreg_Name :: struct { - value: u16, + value: System_Register, name: string, } @@ -757,11 +733,11 @@ SYSREG_NAMES := [?]Sysreg_Name{ {0x7F12, "cntps_cval_el1"}, } -// Name for a packed system-register field, or ok=false when it is not one we -// know -- callers should fall back to printing the raw immediate. +// Name for a system register, or ok=false when it is not one we know -- +// callers should fall back to printing the raw field. @(require_results) -sysreg_name :: proc "contextless" (value: i64) -> (name: string, ok: bool) { - v := u16(value & 0x7FFF) +sysreg_name :: proc "contextless" (sr: System_Register) -> (name: string, ok: bool) { + v := System_Register(u16(sr) & 0x7FFF) lo, hi := 0, len(SYSREG_NAMES) - 1 for lo <= hi { mid := (lo + hi) / 2 diff --git a/core/rexcode/isa/arm64/tablegen/generated/decode_tables.odin b/core/rexcode/isa/arm64/tablegen/generated/decode_tables.odin index e01c4b843..a1b37e39f 100644 --- a/core/rexcode/isa/arm64/tablegen/generated/decode_tables.odin +++ b/core/rexcode/isa/arm64/tablegen/generated/decode_tables.odin @@ -1955,7 +1955,7 @@ DECODE_ENTRIES := [2498]lib.Decode_Entry{ { .TLBI_VAALE1, {.X_REG,.NONE,.NONE,.NONE}, {.RT,.NONE,.NONE,.NONE}, 0xD50887E0, 0xFFFFFFE0, .BASE, {is_64=true, explicit_count=1} }, { .TLBI_VAALE1IS, {.X_REG,.NONE,.NONE,.NONE}, {.RT,.NONE,.NONE,.NONE}, 0xD50883E0, 0xFFFFFFE0, .BASE, {is_64=true, explicit_count=1} }, { .HINT, {.IMM_8,.NONE,.NONE,.NONE}, {.HINT_FIELD,.NONE,.NONE,.NONE}, 0xD503201F, 0xFFFFF01F, .BASE, {explicit_count=1} }, - { .MSR, {.SYS_REG,.IMM_4,.NONE,.NONE}, {.MSR_PSTATE,.BARRIER_FIELD,.NONE,.NONE}, 0xD500401F, 0xFFF8F01F, .BASE, {explicit_count=2} }, + { .MSR, {.PSTATE_FIELD,.IMM_4,.NONE,.NONE}, {.MSR_PSTATE,.BARRIER_FIELD,.NONE,.NONE}, 0xD500401F, 0xFFF8F01F, .BASE, {explicit_count=2} }, { .SVC, {.IMM_16,.NONE,.NONE,.NONE}, {.IMM16,.NONE,.NONE,.NONE}, 0xD4000001, 0xFFE0001F, .BASE, {branch=true, explicit_count=1} }, { .HVC, {.IMM_16,.NONE,.NONE,.NONE}, {.IMM16,.NONE,.NONE,.NONE}, 0xD4000002, 0xFFE0001F, .BASE, {branch=true, explicit_count=1} }, { .SMC, {.IMM_16,.NONE,.NONE,.NONE}, {.IMM16,.NONE,.NONE,.NONE}, 0xD4000003, 0xFFE0001F, .BASE, {branch=true, explicit_count=1} }, diff --git a/core/rexcode/isa/arm64/tablegen/generated/encode_tables.odin b/core/rexcode/isa/arm64/tablegen/generated/encode_tables.odin index f0feb9801..77fa940bf 100644 --- a/core/rexcode/isa/arm64/tablegen/generated/encode_tables.odin +++ b/core/rexcode/isa/arm64/tablegen/generated/encode_tables.odin @@ -492,7 +492,7 @@ ENCODE_FORMS := [2496]lib.Encoding{ // .MRS { .MRS, {.X_REG,.SYS_REG,.NONE,.NONE}, {.RT,.SYS_FIELD,.NONE,.NONE}, 0xD5300000, 0xFFF00000, .BASE, {explicit_count=2} }, // .MSR - { .MSR, {.SYS_REG,.IMM_4,.NONE,.NONE}, {.MSR_PSTATE,.BARRIER_FIELD,.NONE,.NONE}, 0xD500401F, 0xFFF8F01F, .BASE, {explicit_count=2} }, + { .MSR, {.PSTATE_FIELD,.IMM_4,.NONE,.NONE}, {.MSR_PSTATE,.BARRIER_FIELD,.NONE,.NONE}, 0xD500401F, 0xFFF8F01F, .BASE, {explicit_count=2} }, { .MSR, {.SYS_REG,.X_REG,.NONE,.NONE}, {.SYS_FIELD,.RT,.NONE,.NONE}, 0xD5100000, 0xFFF00000, .BASE, {explicit_count=2} }, // .ISB { .ISB, {.IMM_4,.NONE,.NONE,.NONE}, {.BARRIER_FIELD,.NONE,.NONE,.NONE}, 0xD50330DF, 0xFFFFF0FF, .BASE, {explicit_count=1} }, diff --git a/core/rexcode/isa/arm64/tablegen/instruction_table.odin b/core/rexcode/isa/arm64/tablegen/instruction_table.odin index 13fb3296c..a32b04759 100644 --- a/core/rexcode/isa/arm64/tablegen/instruction_table.odin +++ b/core/rexcode/isa/arm64/tablegen/instruction_table.odin @@ -691,7 +691,7 @@ INSTRUCTION_TABLE := [Mnemonic][]Form{ {{.MRS, {.X_REG, .SYS_REG, .NONE, .NONE}, {.RT, .SYS_FIELD, .NONE, .NONE}, 0xD5300000, 0xFFF00000, .BASE, {}}, {written={0}, read={1}, side_effects={.PRIVILEGED}}}, }, .MSR = { - {{.MSR, {.SYS_REG, .IMM_4, .NONE, .NONE}, {.MSR_PSTATE, .BARRIER_FIELD, .NONE, .NONE}, 0xD500401F, 0xFFF8F01F, .BASE, {}}, {side_effects={.PRIVILEGED}}}, + {{.MSR, {.PSTATE_FIELD, .IMM_4, .NONE, .NONE}, {.MSR_PSTATE, .BARRIER_FIELD, .NONE, .NONE}, 0xD500401F, 0xFFF8F01F, .BASE, {}}, {side_effects={.PRIVILEGED}}}, {{.MSR, {.SYS_REG, .X_REG, .NONE, .NONE}, {.SYS_FIELD, .RT, .NONE, .NONE}, 0xD5100000, 0xFFF00000, .BASE, {}}, {written={0}, read={1}, side_effects={.PRIVILEGED}}}, }, .ISB = { diff --git a/core/rexcode/isa/arm64/tables/arm64.encode_forms.bin b/core/rexcode/isa/arm64/tables/arm64.encode_forms.bin index d8d681632c109e5157a8dded583d4ff48bcd65d4..6d8f7d751c7186b621f891c4351a7ac0e1d60e52 100644 GIT binary patch delta 11764 zcmZo@V{T|;UckcWI+>A0*w&SSiHnzkfuZ3N14F}qh5|MQMr*j35LhgMje!XvHVG_N zzz$M3IgmwI1FrfLM23Tb$(w|p^l*;3aqz5 z1EG$g;TBkIf+j*8OFc}XCPE<#OraJ7BcoF&3%j@o1A{}A0LXzIS`17~aIs%tu^Czn zjCM|;EEeJ-3>--65Moeu+Q{Zvf%VpRXd@fA3oJN88`(gJLXbLyflzfi42)q63{0X7 z3=i1nOFiiS|DVADNvwUo)PwVAV#nu8J$MfhV+vznsE2Bv1=bv(!vGQli?z?61=fr# zc6|OUu;u_=gvHGBqriF{ki?qjM}hSsiyfXH1=j1Ji?D-ve#|Yf<^UwY=J~h4nvum0 z&%XuM9H7U*$QZ`J#39PS07?rz5B@VGAc?g!NHLs&i%mW#C~ON?J&OUPxZ}!z_k35B@V0=!0yUEGPswp`jrPtU3WK198KFhA6P=1bu|5pmYYd2`n}_ z5n;lChFf6O1qL9qAttaiM1kFvfF#xevk5FVd83f9Ce+2CqzN|L0AXKC!!5A83czBM z-wIiZdN43BsDg4Y1A_KWMJf_5-L26niZJzR_fF6ICi>Fg^TgQ#oXXx{BSXM21ZW?24+YQnlOMu(8-;F z2_d!xEEeQ}tj-iH=H$V^B!*D96)YI!$-rdiHQ7*9xZaC_SyLSpHRcQq4D}32-VBUB z3=GWDAR&jH;DXb^n}G=-_7f}?;EimR1lUxNI)qITU@?$7Uj_zdSq26M9)}&^q7bAG zCRWem@B=IeQs~FPz%0kWz`%l}5Fv(8=g+{vtjxf`z>$D35FrLv$BA&XEy&S~4&Dr0 z2(em_SUpIP8zHzCBnT4YL5Tf@iSfe44!{kR4Ps!>3T0qmaA;^{c<|squY)&(Vh{s^ z7f6hup;Z7XW*5Z35C|4yc*xN3;6J~E4=AMTp+U_64Qd~xpk{yuwGRU$EVy_Wpg#6t zU_yvNeeA=)2oEhJbqFzpI(TT+DSG_IAY=dsA)|v210n<&pdskP zfCxbbXbAc+AVRPKVqU$24+ByVK7|CK4{{Jbg#@7w10o0&ph4&h3PNZII#`0DiNV1a zDYP6cz-bF41`h=!F@FYzdT2s|D)d7#kO69-ACiF#2z77+k;D)o2vz5g6rBwa^8);l z>^M*l5p?ipV1#RafY1yVTL2LY2td;8PzmvI0Fnb8Dj+@%KuQZpVsP^kpz7)akql&j z8W@OVAOlokAd-PdVsHZ$pz4BGj6Mv^tO}sKs0j|4gb)TMCXkpSNNgootN^6W7pm@n=42}=E?W>6 zq~rjS5inji_noYVky5=b-1dXVoLpiTm5_M5CI4Y3|1!=MYZiiZbe zJ;<>PP$z{VIf()4q%g4ch0?OXh}a3RSU?1ly7^Fb5lHIhL)Aqh)W!a}&jHr#5QPx@Gao7zjU;y81EMYlNo+n; zEEXYF6W_t`=fQslhgb$CpUDX_A~rq@Ow95O3^fc8iG(-?Mkct}39#aVc!U9eUweA_`Uf2WCJ5$biW=Wi~RpZ0?pl#;FPEEbu7EfwCZDLlXlJ4-Zr<0WQYH#TB}_ zO8u{}s2c+VsIw!_z)&O)>g{;UW?*ug++%HB52|Klz!fkgZ9B|?gdRi;S~$;v6uJNY9Ogg@U5MBpm>9Uw1&bZ9fr!n8_!BG!t10Hf?Wkv9V1QaO7s(O^s3mieEMb6J zG8a;^gAHteS~3sG5?G--A4v>WZZ3dZ%)rn9D(15PGXyL^Qg{F)_@BXHA(9xZOk0E` z1}l~pBO3@UMHVBeI{*=LSOSV!16vVr?gb@&2WZAx3d$A?%&eg7;{eU;%aC&~RNXR= zy2*{U!u6oc2Fe5V9SjZs|1%^k2gxunvx3D=fW-<{fI5IaOkhEU4p19_p;zbB!b+%3@(c_OF!NR-%xkEJnzssJUVQ`1z*PtX8x)`hu7>y><3t^U_01$h}Z(Cy6qr!lM|6lNPx=h0Ld^wR3|`9*okDq1E{*4Aa#>BB1{l~ zxnUPb24aGM0@Q@v2onTgZrBY{H<{4^?h65!8}@)?peDfFuouY$m>c$j)J+aVn4kc2 z!#Uq;B#@gb4;PHyi@V zKuj=zx#2Lv1Ou2G4ujN9c65Y?g8|G9M?f-A6JTyQiev)J4M#!hCQn3|-~e;OF^~+z z1P7QKjw4KPfVtr~NZsUzNG8DCZ~`O)H38;^lSn4O+;9@4ZnB{h+!p~bH=F{=KuidL zx#2XzgaDWuPJ`40p^CYAa#>3B1}ktx#1j024X@2%nj!e zCM3Yza2}*?vZ6EG7YQ&oTmZ>HO@O)KB9aL(H(Ug%n_P%6p#bKFOCTAD2?a1WTt=8s z0CU4-kh;kSkxYQO;R;9wY68p+SCLGBx#22E-DE)*xGx%DZny@Lftb($bHjCn2@Nne zTnDL}oQPxs%ndg{GEfs>Zn%kL0?Z9JLFy)NM3_*s0Ne;+O}GV;ftXOU0Ne;+Ex3&^ zq2>Wp-EEM%$&9XWU;KfYa0es;XdT4@})dkl5sf$R>cxdDeu-AQ^}oY92tvo*=~jEP#qV1&K}mh-88S)V^mR*FjBC zfT%8b4pI#jOMt3-4pKMS(G3v}FcV&YWFV^lz)X0FFyRl(gqI+7n^mCntv?CND3KA*P_9 z5WZQ+kIh6goIy+5h=C!5gP-BgkN->ww-^Nk;9~wTF+sub$&O9JwlEn1e}+FFz^a9X zVPXpWpqdk8f`|xQ%pWEuCKf(bq_LXoz?Yqq=C>{=^&nUb>cRUU3mLSuL1HiuJ^*_#5y=FY2Ol8Y2le0s zkbO`SU>tm385EE2jzI_bx?PSMxcsQuQ{P!4Pp9(CwJ_gwb zH38<^Cm`QWo`_@u%zsai?SsbV6OesS6JWl50`l$The#&C{PzUeK4@${1=$BN!35^p zry$=>Htc}=!UX2OrwIE@V6piWWFOQ7m~Wqgd^@=j$po1Ho*~-@jm>8u`=BPkeESUK z+sPM^On~|C8M1xQ*n9@E4{8F;x6eSn-K^ND%?Qi4AskQ(UxF;0oY)2NAgCOK<^PvZ z4}!&@`Tr%!H9uj2`mC%Gm5}U(j~B{d(9{YE3=otqUjBz zkU;q4g-9mABJ~ZU7_2m30!yxM8HM)-5`%f;3!{Kg_~gc3cu=;$ zyzzxm1fd#QhJIz_2Rp);fuRRx(^rs9lP@An=z*F24P-VX;Co;>{~Mza%w0V&o4$c; znylCdcf%Bz+228CLrj)YAhV$+z#`)p!WUCuk?{*;(`3PZxG(0weDND(HpGNEFkk#e_+k#s7k@xD zO-@8I0p^Q8AhV$+zqnf)JRHpGM$SeE~f@I?#ECI%)@iV8$B0cJJ>6HpDBTvNk9@V z<_8lKl!A#d@iF{)3|1#36*1XyqOc}RhJ}ye&vUShh%{Wx4<;ri6EV4V;=B3?$p|e| zZ8HWI#yp0WhyR%xSeT?Dq@ZF;|!D7-8(oiv$Jcc>X!D2EIGEgy&Jcd2*!D5mT zj0{?)EDQ`Xj8Mmd%!7$B`9U1Z!Xyn<$HySU0(BD$lT5_qACqneyD@-gGaoQB7(HM< z@Snkfm5B)b9b|Ct)tm;?j_U}AX;Ef6tTS=sQ- zYEv$9fQC}FKuzxg2OowH|Nk>Nh%pKIFff3{N*sI`zCgr8U}6;xJ`6t~Vq!3{8V4WH zSQALEWP}fcmLteO2VRB;|MxQ`h%rfl#GK?A7#tjU8J~UWPv)F>xjVm?aG`OT?KFmLxze5l6Bl0cwdj6U-8Zh6Jb`;!FrT5aw)12m|m5Dsi$fCjY`!htOeprGE*lpu|8U<1UCdL{>HBuf;amPjL6 zq5!o-8p#p`s3p=!mMB0ikwIAE0I`J0K?Y%m0?Z>aAUo;X)jB9nm6<}(WpaEJynX!(XPFgP$Q0nZ&L1To1g2TxwOQrI?_LCZG`By)t}!Giz1 z1wl+Y%7F|CAk_>E4+Iz<{O3;yVzN*UWXOexEdZGS60=keocwX6ur18&1yHktL1sfu zZD;|Tnh?ySpbWFA0cuk)ldf{$WXDw?6ToIGFhI=?X0lWcWGDdHw*V#S8P+x=~eBppF737PDU^hTQ=mEs+f>2}^ zLro23(pL^-NCumF0AgxED9F^whO0ro0K51B)a-&VCONo^4?s*!2t$Mo0|PW{!az1n zZUmbEaRUQXbvTl0SV)G0R6|0S0Tz-GObW_@lP|7@hXVrx)WwlZvWl=!V|W4ywMZs; zMQB_!fW#L3=S_%YQcw(@thff`3rO56K>U{w$z-7ji+crV{6sQYDnjF@0VWp3B&QfS zxo{2K4Gj%Xz;Tff1u`4rVwhM#6qBxEAVVTJBom-EMS*OZd=Tsga7ZqInH|j}5BG%w zWc5P=NDS_arx2T>K{ibmTnq9AB<>eL&5j0{4N1Wc2vgy{H~6aIuweF=4paD!7;kTx>O5 zOcXA*1}0X|AO;s)3ln4zhl{O)i%G!6*2Bdl;bI%$Vp4Fijc_q(xY#DRm<(7EC>?Y0vD5mi*04{-28l74I`+*2Ohv>aF_`i)Maou1PNl$pe}<0c>I+i;4l*- zD0;wR3{Z84k<>9j)g3`n=O76&? z6G-X~K*StQBCCVw4LFIc4kG4o3RxY NneBWw-#Dnj2mls96chje delta 11765 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 / emit_ overload group. @@ -26,7 +26,8 @@ package main // SVE Z register / Z pair / Z quad -> u8 / op_z_* (suffix z) // SVE predicate (P_REG / merge / zero / gov) -> u8 / Register(REG_P|..) (suffix p) // all immediates (incl ZA tile, SME slice, -> i64 / op_imm (suffix i) -// patterns, bitmask, sysreg, HW, NZCV, ...) +// patterns, bitmask, HW, NZCV, ...) +// MRS/MSR system register -> System_Register / op_sysreg (suffix s) // PC-relative label -> u32 / op_label (suffix l) // memory -> Memory / op_mem (suffix m) // condition code -> Cond / op_cond (suffix c) @@ -69,6 +70,7 @@ Operand_Category :: enum { REL, // u32 label -> op_label (1 param, suffix l) MEM, // Memory -> op_mem (1 param, suffix m) COND, // Cond -> op_cond (1 param, suffix c) + SYSREG, // System_Register -> op_sysreg (1 param, suffix s) SHIFTED, // Register + Shift_Type + u8 -> op_shifted (3 params, suffix sh) EXTENDED, // Register + Extend + u8 -> op_extended (3 params, suffix ex) } @@ -133,6 +135,8 @@ operand_category :: proc(t: a.Operand_Type) -> Operand_Category { return .MEM case .COND, .COND_NOT_AL: return .COND + case .SYS_REG: + return .SYSREG case .W_SHIFTED, .X_SHIFTED: return .SHIFTED case .W_EXTENDED, .X_EXTENDED: @@ -177,6 +181,7 @@ operand_suffix :: proc(t: a.Operand_Type) -> string { case .REL: return "l" case .MEM: return "m" case .COND: return "c" + case .SYSREG: return "s" case .SHIFTED: return "sh" case .EXTENDED: return "ex" } @@ -255,6 +260,8 @@ operand_primary_names :: proc(sig: Operand_Signature) -> [4][3]string { result[i][0] = "mem" case .COND: result[i][0] = "cond" + case .SYSREG: + result[i][0] = "sysreg" case .SHIFTED: rn := reg_name(i, ®_count) result[i][0] = rn @@ -290,6 +297,8 @@ param_list :: proc(sig: Operand_Signature) -> [dynamic]Param { append(¶ms, Param{decl = fmt.tprintf("%s: Memory", names[i][0]), name = names[i][0]}) case .COND: append(¶ms, Param{decl = fmt.tprintf("%s: Cond", names[i][0]), name = names[i][0]}) + case .SYSREG: + append(¶ms, Param{decl = fmt.tprintf("%s: System_Register", names[i][0]), name = names[i][0]}) case .SHIFTED: append(¶ms, Param{decl = fmt.tprintf("%s: Register", names[i][0]), name = names[i][0]}) append(¶ms, Param{decl = fmt.tprintf("%s: Shift_Type", names[i][1]), name = names[i][1]}) @@ -363,6 +372,8 @@ write_operand_expr :: proc(sb: ^strings.Builder, t: a.Operand_Type, names: [3]st fmt.sbprintf(sb, "op_mem(%s)", names[0]) case .COND: fmt.sbprintf(sb, "op_cond(%s)", names[0]) + case .SYSREG: + fmt.sbprintf(sb, "op_sysreg(%s)", names[0]) case .SHIFTED: fmt.sbprintf(sb, "op_shifted(%s, %s, %s)", names[0], names[1], names[2]) case .EXTENDED: @@ -398,7 +409,7 @@ uses_plain_constructors :: proc(sig: Operand_Signature) -> bool { .V_4H_FP16, .V_8H_FP16: return false // needs op_v_* } - case .IMM, .REL, .MEM, .COND: + case .IMM, .REL, .MEM, .COND, .SYSREG: // fine case: return false // ZREG / PREG / SHIFTED / EXTENDED