rexcode/arm32: the operands that are tokens, and a register field one bit short

The last of the A32 sweep's disagreements, and they were mostly the
same shape: an operand the syntax names but no field encodes, left
printing as `#0`.

MRS names APSR or SPSR by the R bit; VMRS and VMSR name FPSCR and its
neighbours out of bits 19:16, which their masks had pinned shut so the
register could not vary at all; SETEND names LE or BE by the E bit.
Those are bare tokens in the syntax, which is what the special-register
classes already model, so the endian pair joins them as a register
class of its own. DBG read the whole eight-bit hint field where its
option is only the low four, so it printed the fixed bits above it.

RFE and SRS name their addressing mode the way LDM and STM do, so they
are four mnemonics each rather than one, and the P and U bits that pick
the mode are fixed bits of each form -- they had been left out of the
mask entirely, so every one of the eight words decoded as the DA form.
The writeback bit rides in the base register for RFE and in the
implicit SP for SRS.

VORR and VBIC against a modified immediate had no forms at all. Those
words fell through to the shift-by-immediate family that sits beside
them, and decoded as VSRA, VQSHRN and VQRSHRN with a shift of zero --
which is not a shift any of them can take.

The register field in an operand was fifteen bits, on the reasoning
that a register's raw value never passes 0x401F. Two classes do: the
coprocessor registers at 0x8000, and now the endian tokens at 0x9000.
Both were truncating silently. The field is sixteen bits, which fills
the word exactly. A memory base or index is always a GPR, so those stay
as they are.

The A32 sweep now round-trips 984 of its 1183 entries byte-exact
through llvm-mc, with nothing left that llvm and this disagree on: 159
are words llvm's own disassembly cannot assemble back, 38 are reserved
encodings, and the last two are PSB CSYNC and TSB CSYNC, which llvm
does not implement for AArch32 at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018UmHLRF11EoWwNWCJ7JGaA
This commit is contained in:
Brendan Punsky
2026-08-29 01:54:19 -04:00
committed by Flāvius
parent d739a503cd
commit 8c5ffd7b4c
21 changed files with 1761 additions and 1555 deletions

View File

@@ -171,7 +171,7 @@ find_and_decode :: proc(word: u32, mode: Mode, ilen: u32, inst: ^Instruction, in
// LDM/STM carry the writeback in bit 21; nothing else in the operand
// model records it, and without it the two forms print identically.
for k in 0 ..< len(e.enc) {
if e.enc[k] == .A32_REG_LIST {
if e.enc[k] == .A32_REG_LIST || e.enc[k] == .RN_A32_WB || e.enc[k] == .IMPL_SP {
inst.writeback = (word >> 21) & 1 != 0
break
}
@@ -455,6 +455,13 @@ unpack_operand :: proc(word: u32, enc: Operand_Encoding, ot: Operand_Type) -> Op
// Only cmode 1111 expands to a float; the rest are bit patterns.
if cmode == 0b1111 { return op_float_imm(v) }
return op_hex_imm(v)
case .DBG_OPTION: return op_imm(i64(word & 0xF))
case .MRS_SPEC_REG: return op_reg(Register(REG_SREG | u16(((word >> 22) & 1) * 2)))
case .VFP_SPEC_REG: return op_reg(Register(REG_FPSC | u16((word >> 16) & 0xF)))
case .SETEND_ENDIAN: return op_reg(Register(REG_ENDIAN | u16((word >> 9) & 1)))
case .IMPL_SP: return op_reg(SP)
case .MODE_IMM5: return op_imm(i64(word & 0x1F))
case .RN_A32_WB: return op_reg(Register(REG_GPR | u16((word >> 16) & 0xF)))
case .VM_S_PLUS1:
// The second of a consecutive pair; only the first is encoded.
return op_reg(Register(REG_SPR | u16(((word & 0xF) << 1 | ((word >> 5) & 1)) + 1)))

View File

@@ -312,7 +312,7 @@ operand_matches_inline :: #force_inline proc "contextless" (op: ^Operand, ot: Op
return true
case .IMM, .IMM_MOD, .IMM_T32_MOD, .IMM12, .IMM5, .IMM5_W,
.IMM4, .IMM4_SAT, .IMM8, .IMM3, .IMM_HINT, .IMM_BARRIER,
.IMM_ENDIAN, .IMM_IFLAGS, .IMM_BANKED, .IMM_SYSM,
.IMM_IFLAGS, .IMM_BANKED, .IMM_SYSM,
.IMM_COPROC, .IMM_COPROC_OP, .NEON_IMM, .IMM16_LO_HI:
// A modified immediate reaches an immediate slot as an expanded bit
// pattern or a float, so all three kinds are the same slot's shape.
@@ -328,8 +328,12 @@ operand_matches_inline :: #force_inline proc "contextless" (op: ^Operand, ot: Op
return op.kind == .MEMORY || op.kind == .RELATIVE
case .COPROC_REG, .COPROC_NUM:
return op.kind == .REGISTER || op.kind == .IMMEDIATE
case .IMM_ENDIAN:
return op.kind == .REGISTER
case .PSR_FIELD:
return op.kind == .IMMEDIATE
// APSR, SPSR and the endian tokens are named registers in the syntax
// even where no field encodes them.
return op.kind == .IMMEDIATE || op.kind == .REGISTER
case .VPR, .QPR_MVE:
return op.kind == .REGISTER && is_qpr(op.reg)
case .QPR_MVE_LIST:
@@ -497,6 +501,13 @@ pack_operand_inline :: #force_inline proc(
return (u32(reg_hw(op.reg)) & 0x7) << 17
case .VM_Q_MVE:
return (u32(reg_hw(op.reg)) & 0x7) << 1
case .DBG_OPTION: return u32(op.immediate) & 0xF
case .MRS_SPEC_REG: return 0 // the R bit is a fixed bit of the form
case .VFP_SPEC_REG: return (u32(reg_hw(op.reg)) & 0xF) << 16
case .SETEND_ENDIAN: return (u32(reg_hw(op.reg)) & 1) << 9
case .IMPL_SP: return 0
case .MODE_IMM5: return u32(op.immediate) & 0x1F
case .RN_A32_WB: return (u32(reg_hw(op.reg)) & 0xF) << 16
case .VM_S_PLUS1:
return 0 // only the first of the pair is encoded
case .NEON_LANE_VN_32:
@@ -953,7 +964,7 @@ neon_lane_shape :: #force_inline proc "contextless" (e: Operand_Encoding) -> (sh
@(private="file", require_results)
writeback_matches :: #force_inline proc "contextless" (inst: ^Instruction, f: ^Encoding) -> bool {
for e in f.enc {
if e == .A32_REG_LIST {
if e == .A32_REG_LIST || e == .RN_A32_WB || e == .IMPL_SP {
return ((f.bits >> 21) & 1 != 0) == inst.writeback
}
}

View File

@@ -326,6 +326,13 @@ Operand_Encoding :: enum u8 {
VM_Q_MVE,
VFP_IMM8,
VM_S_PLUS1, // the second S register of a consecutive pair
DBG_OPTION, // DBG's option, bits 3:0 -- not the wider hint field
MRS_SPEC_REG, // APSR or SPSR, by the R bit
VFP_SPEC_REG, // VMRS/VMSR system register, bits 19:16
SETEND_ENDIAN, // LE or BE, by the E bit
IMPL_SP, // an SP the syntax names but no field encodes
MODE_IMM5, // processor mode, bits 4:0 (SRS)
RN_A32_WB, // base register whose writeback rides in bit 21
NEON_LANE_VN_32, // Vn:N with the 32-bit lane index in bit 21 // VFP immediate (VMOV.F32/F64 #imm)
NEON_IMM8_ABCDEFGH, // bits 18-16 (abc) + bits 3-0 (defgh)
NEON_CMODE, // bits 11-8 (cmode for VMOV/VMVN immediate)

View File

@@ -620,10 +620,22 @@ inst_swp_r_r_r :: #force_inline proc "contextless" (dst: Register, s
emit_swp_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_swp_r_r_r(dst, src, src2)) }
inst_swpb_r_r_r :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .SWPB, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), {}}} }
emit_swpb_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_swpb_r_r_r(dst, src, src2)) }
inst_rfe_r :: #force_inline proc "contextless" (dst: Register) -> Instruction { return Instruction{mnemonic = .RFE, operand_count = 1, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), {}, {}, {}}} }
emit_rfe_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register) { append(instructions, inst_rfe_r(dst)) }
inst_srs_imm :: #force_inline proc "contextless" (imm: i64) -> Instruction { return Instruction{mnemonic = .SRS, operand_count = 1, mode = .A32, cond = 14, length = 4, ops = {op_imm(imm), {}, {}, {}}} }
emit_srs_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_srs_imm(imm)) }
inst_rfeda_r :: #force_inline proc "contextless" (dst: Register) -> Instruction { return Instruction{mnemonic = .RFEDA, operand_count = 1, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), {}, {}, {}}} }
emit_rfeda_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register) { append(instructions, inst_rfeda_r(dst)) }
inst_rfedb_r :: #force_inline proc "contextless" (dst: Register) -> Instruction { return Instruction{mnemonic = .RFEDB, operand_count = 1, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), {}, {}, {}}} }
emit_rfedb_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register) { append(instructions, inst_rfedb_r(dst)) }
inst_rfeia_r :: #force_inline proc "contextless" (dst: Register) -> Instruction { return Instruction{mnemonic = .RFEIA, operand_count = 1, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), {}, {}, {}}} }
emit_rfeia_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register) { append(instructions, inst_rfeia_r(dst)) }
inst_rfeib_r :: #force_inline proc "contextless" (dst: Register) -> Instruction { return Instruction{mnemonic = .RFEIB, operand_count = 1, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), {}, {}, {}}} }
emit_rfeib_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register) { append(instructions, inst_rfeib_r(dst)) }
inst_srsda_r_imm :: #force_inline proc "contextless" (dst: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SRSDA, operand_count = 2, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_imm(imm), {}, {}}} }
emit_srsda_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, imm: i64) { append(instructions, inst_srsda_r_imm(dst, imm)) }
inst_srsdb_r_imm :: #force_inline proc "contextless" (dst: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SRSDB, operand_count = 2, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_imm(imm), {}, {}}} }
emit_srsdb_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, imm: i64) { append(instructions, inst_srsdb_r_imm(dst, imm)) }
inst_srsia_r_imm :: #force_inline proc "contextless" (dst: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SRSIA, operand_count = 2, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_imm(imm), {}, {}}} }
emit_srsia_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, imm: i64) { append(instructions, inst_srsia_r_imm(dst, imm)) }
inst_srsib_r_imm :: #force_inline proc "contextless" (dst: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SRSIB, operand_count = 2, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_imm(imm), {}, {}}} }
emit_srsib_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, imm: i64) { append(instructions, inst_srsib_r_imm(dst, imm)) }
inst_cdp_cpn_cpop_crd_crd :: #force_inline proc "contextless" (dst: Register, imm: i64, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .CDP, operand_count = 4, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_imm(imm), op_reg(src), op_reg(src2)}} }
emit_cdp_cpn_cpop_crd_crd :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, imm: i64, src: Register, src2: Register) { append(instructions, inst_cdp_cpn_cpop_crd_crd(dst, imm, src, src2)) }
inst_cdp2_cpn_cpop_crd_crd :: #force_inline proc "contextless" (dst: Register, imm: i64, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .CDP2, operand_count = 4, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_imm(imm), op_reg(src), op_reg(src2)}} }
@@ -742,10 +754,10 @@ emit_vmov_r_r_s_s :: #force_inline proc(instructions: ^[dynamic]Instruc
emit_vmov_r_dlane :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, lane: u8) { append(instructions, inst_vmov_r_dlane(dst, src, lane)) }
emit_vmov_qlane_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, lane: u8, src: Register) { append(instructions, inst_vmov_qlane_r(dst, lane, src)) }
emit_vmov_qlane_qlane_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, lane: u8, src: Register, lane2: u8, src2: Register, src3: Register) { append(instructions, inst_vmov_qlane_qlane_r_r(dst, lane, src, lane2, src2, src3)) }
inst_vmrs_r :: #force_inline proc "contextless" (dst: Register) -> Instruction { return Instruction{mnemonic = .VMRS, operand_count = 1, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), {}, {}, {}}} }
emit_vmrs_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register) { append(instructions, inst_vmrs_r(dst)) }
inst_vmsr_r :: #force_inline proc "contextless" (dst: Register) -> Instruction { return Instruction{mnemonic = .VMSR, operand_count = 1, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), {}, {}, {}}} }
emit_vmsr_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register) { append(instructions, inst_vmsr_r(dst)) }
inst_vmrs_r_psr :: #force_inline proc "contextless" (dst: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .VMRS, operand_count = 2, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_imm(imm), {}, {}}} }
emit_vmrs_r_psr :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, imm: i64) { append(instructions, inst_vmrs_r_psr(dst, imm)) }
inst_vmsr_psr_r :: #force_inline proc "contextless" (imm: i64, src: Register) -> Instruction { return Instruction{mnemonic = .VMSR, operand_count = 2, mode = .A32, cond = 14, length = 4, ops = {op_imm(imm), op_reg(src), {}, {}}} }
emit_vmsr_psr_r :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, src: Register) { append(instructions, inst_vmsr_psr_r(imm, src)) }
inst_vldr_s_mem :: #force_inline proc "contextless" (dst: Register, src: Memory) -> Instruction { return Instruction{mnemonic = .VLDR, operand_count = 2, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_mem(src), {}, {}}} }
emit_vldr_s_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Memory) { append(instructions, inst_vldr_s_mem(dst, src)) }
inst_vstr_s_mem :: #force_inline proc "contextless" (dst: Register, src: Memory) -> Instruction { return Instruction{mnemonic = .VSTR, operand_count = 2, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_mem(src), {}, {}}} }
@@ -846,9 +858,13 @@ inst_vabdl_q_d_d :: #force_inline proc "contextless" (dst: Register, s
emit_vabdl_q_d_d :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_vabdl_q_d_d(dst, src, src2)) }
inst_vand_d_d_d :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .VAND, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), {}}} }
emit_vand_d_d_d :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_vand_d_d_d(dst, src, src2)) }
inst_vbic_d_imm :: #force_inline proc "contextless" (dst: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .VBIC, operand_count = 2, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_imm(imm), {}, {}}} }
inst_vbic_d_d_d :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .VBIC, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), {}}} }
emit_vbic_d_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, imm: i64) { append(instructions, inst_vbic_d_imm(dst, imm)) }
emit_vbic_d_d_d :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_vbic_d_d_d(dst, src, src2)) }
inst_vorr_d_imm :: #force_inline proc "contextless" (dst: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .VORR, operand_count = 2, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_imm(imm), {}, {}}} }
inst_vorr_d_d_d :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .VORR, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), {}}} }
emit_vorr_d_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, imm: i64) { append(instructions, inst_vorr_d_imm(dst, imm)) }
emit_vorr_d_d_d :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_vorr_d_d_d(dst, src, src2)) }
inst_vorn_d_d_d :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .VORN, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), {}}} }
emit_vorn_d_d_d :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_vorn_d_d_d(dst, src, src2)) }
@@ -1885,10 +1901,22 @@ inst_swp :: inst_swp_r_r_r
emit_swp :: emit_swp_r_r_r
inst_swpb :: inst_swpb_r_r_r
emit_swpb :: emit_swpb_r_r_r
inst_rfe :: inst_rfe_r
emit_rfe :: emit_rfe_r
inst_srs :: inst_srs_imm
emit_srs :: emit_srs_imm
inst_rfeda :: inst_rfeda_r
emit_rfeda :: emit_rfeda_r
inst_rfedb :: inst_rfedb_r
emit_rfedb :: emit_rfedb_r
inst_rfeia :: inst_rfeia_r
emit_rfeia :: emit_rfeia_r
inst_rfeib :: inst_rfeib_r
emit_rfeib :: emit_rfeib_r
inst_srsda :: inst_srsda_r_imm
emit_srsda :: emit_srsda_r_imm
inst_srsdb :: inst_srsdb_r_imm
emit_srsdb :: emit_srsdb_r_imm
inst_srsia :: inst_srsia_r_imm
emit_srsia :: emit_srsia_r_imm
inst_srsib :: inst_srsib_r_imm
emit_srsib :: emit_srsib_r_imm
inst_cdp :: inst_cdp_cpn_cpop_crd_crd
emit_cdp :: emit_cdp_cpn_cpop_crd_crd
inst_cdp2 :: inst_cdp2_cpn_cpop_crd_crd
@@ -1983,10 +2011,10 @@ inst_vcvtr :: inst_vcvtr_s_s
emit_vcvtr :: emit_vcvtr_s_s
inst_vmov :: proc{ inst_vmov_s_s, inst_vmov_s_imm8, inst_vmov_r_r_d, inst_vmov_r_r_s_s, inst_vmov_r_dlane, inst_vmov_qlane_r, inst_vmov_qlane_qlane_r_r }
emit_vmov :: proc{ emit_vmov_s_s, emit_vmov_s_imm8, emit_vmov_r_r_d, emit_vmov_r_r_s_s, emit_vmov_r_dlane, emit_vmov_qlane_r, emit_vmov_qlane_qlane_r_r }
inst_vmrs :: inst_vmrs_r
emit_vmrs :: emit_vmrs_r
inst_vmsr :: inst_vmsr_r
emit_vmsr :: emit_vmsr_r
inst_vmrs :: inst_vmrs_r_psr
emit_vmrs :: emit_vmrs_r_psr
inst_vmsr :: inst_vmsr_psr_r
emit_vmsr :: emit_vmsr_psr_r
inst_vldr :: inst_vldr_s_mem
emit_vldr :: emit_vldr_s_mem
inst_vstr :: inst_vstr_s_mem
@@ -2067,10 +2095,10 @@ inst_vabdl :: inst_vabdl_q_d_d
emit_vabdl :: emit_vabdl_q_d_d
inst_vand :: inst_vand_d_d_d
emit_vand :: emit_vand_d_d_d
inst_vbic :: inst_vbic_d_d_d
emit_vbic :: emit_vbic_d_d_d
inst_vorr :: inst_vorr_d_d_d
emit_vorr :: emit_vorr_d_d_d
inst_vbic :: proc{ inst_vbic_d_imm, inst_vbic_d_d_d }
emit_vbic :: proc{ emit_vbic_d_imm, emit_vbic_d_d_d }
inst_vorr :: proc{ inst_vorr_d_imm, inst_vorr_d_d_d }
emit_vorr :: proc{ emit_vorr_d_imm, emit_vorr_d_d_d }
inst_vorn :: inst_vorn_d_d_d
emit_vorn :: emit_vorn_d_d_d
inst_veor :: inst_veor_d_d_d

View File

@@ -207,8 +207,9 @@ Mnemonic :: enum u16 {
// -------------------------------------------------------------------------
// ARMv6 / Return-from-Exception
// -------------------------------------------------------------------------
RFE, // return from exception
SRS, // store return state
// The addressing mode is part of the name, as it is for LDM and STM.
RFEDA, RFEDB, RFEIA, RFEIB, // return from exception
SRSDA, SRSDB, SRSIA, SRSIB, // store return state
// -------------------------------------------------------------------------
// Coprocessor (legacy CP-space; many subsumed by VFP/NEON)

View File

@@ -67,8 +67,9 @@ Index_Mode :: enum u8 {
// multiplied by four in every Instruction. Field syntax and composite
// literals are unchanged, so this is invisible to callers.
//
// A Register's raw value never exceeds REG_QPR|31 = 0x401F, so 15 bits hold
// one losslessly (index uses Register(0), not a high sentinel, for "absent").
// A memory base or index is always a GPR, whose raw value never exceeds
// REG_GPR|15 = 0x100F, so 15 bits hold one losslessly (index uses
// Register(0), not a high sentinel, for "absent").
// `disp` gets 19 bits (+/-262,143) against a worst case of 4,095 -- the imm12
// of an A32 load -- so there is ~64x headroom.
Memory :: bit_field u64 {
@@ -115,14 +116,16 @@ Operand :: struct #packed {
// op.shift_type, op.shift_amt and op.lane still read and write
// exactly as they did when these were separate fields.
using _: bit_field u32 {
reg: Register | 15,
// Sixteen bits, not fifteen: the class nibble reaches 0x9000 for
// the endian tokens and 0x8000 for the coprocessor registers,
// and both were silently truncating.
reg: Register | 16,
shift_type: Shift_Type | 4, // GPR_SHIFTED; .LSL/0 when plain
shift_amt: u8 | 6, // 0..32, or the Rs index for RSR
lane: u8 | 5, // SIMD lane for DPR_ELEM / QPR_ELEM
// Whether `lane` means anything. Lane 0 is a real index -- `d0[0]`
// is not `d0` -- so it cannot be spelled by lane == 0.
has_lane: bool | 1,
// 1 bit spare
},
mem: Memory,
immediate: i64,

View File

@@ -501,6 +501,8 @@ write_register :: proc(sb: ^strings.Builder, r: Register, uppercase: bool = fals
}
case REG_COPROC:
fmt.sbprintf(sb, "c%d", hw)
case REG_ENDIAN:
strings.write_string(sb, hw == 0 ? "le" : "be")
case:
fmt.sbprintf(sb, "?%d", hw)
}

View File

@@ -35,6 +35,9 @@ REG_SREG :: u16(0x5000)
REG_FPSC :: u16(0x6000)
REG_BANKED :: u16(0x7000)
REG_COPROC :: u16(0x8000)
// SETEND names its argument `le` or `be`. That is a bare token in the syntax,
// which is what the special-register classes above already model.
REG_ENDIAN :: u16(0x9000)
REG_CLASS_MASK :: u16(0xF000)
REG_HW_MASK :: u16(0x0FFF)
@@ -160,6 +163,9 @@ SPSR :: Register(REG_SREG | 2)
// values rather than expanding the Register set.
// FPSCR / FPSID and friends
LE :: Register(REG_ENDIAN | 0)
BE :: Register(REG_ENDIAN | 1)
FPSID :: Register(REG_FPSC | 0)
FPSCR :: Register(REG_FPSC | 1)
MVFR2 :: Register(REG_FPSC | 5)

View File

@@ -832,7 +832,7 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{
// MSR / MRS (status reg access)
.MRS = {
{.MRS, {.GPR, .PSR_FIELD, .NONE, .NONE}, {.RD, .NONE, .NONE, .NONE}, 0x010F0000, 0x0FBF0FFF, .BASE, .A32, {}, {}},
{.MRS, {.GPR, .PSR_FIELD, .NONE, .NONE}, {.RD, .MRS_SPEC_REG, .NONE, .NONE}, 0x010F0000, 0x0FBF0FFF, .BASE, .A32, {}, {}},
// T32 MRS: high=11110011 1110 1111 low=10 0 0 Rd 0000 0000
{.MRS, {.GPR, .PSR_FIELD, .NONE, .NONE}, {.RD_T32, .NONE, .NONE, .NONE}, 0xF3EF8000, 0xFFFFF0FF, .V6T2, .T32, {thumb32=true, cond_in_28=false}, {}},
},
@@ -849,7 +849,7 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{
.CPS = { {.CPS, {.IMM_IFLAGS, .NONE, .NONE, .NONE}, {.CPS_IFLAGS, .NONE, .NONE, .NONE}, 0xF1000000, 0xFFF1FE20, .V6, .A32, {cond_in_28=false}, {}} },
// SETEND (deprecated in ARMv8): 1111 0001 0000 0001 0000 000E 0000 0000
.SETEND = { {.SETEND, {.IMM_ENDIAN, .NONE, .NONE, .NONE}, {.NONE, .NONE, .NONE, .NONE}, 0xF1010000, 0xFFFFFDFF, .V6, .A32, {cond_in_28=false, deprecated=true}, {}} },
.SETEND = { {.SETEND, {.IMM_ENDIAN, .NONE, .NONE, .NONE}, {.SETEND_ENDIAN, .NONE, .NONE, .NONE}, 0xF1010000, 0xFFFFFDFF, .V6, .A32, {cond_in_28=false, deprecated=true}, {}} },
// SETPAN (ARMv8.1): A32 = 1111 0001 0001 0000 0000 0000 imm1 0000 0000 → bit 9 = imm
// T16: 1011 0110 0001 0 imm1 000 → bit 3 = imm
@@ -887,7 +887,7 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{
{.SEV, {.NONE, .NONE, .NONE, .NONE}, {.NONE, .NONE, .NONE, .NONE}, 0xF3AF8004, 0xFFFFFFFF, .V6T2, .T32, {thumb32=true, cond_in_28=false}, {}},
},
.SEVL = { {.SEVL, {.NONE, .NONE, .NONE, .NONE}, {.NONE, .NONE, .NONE, .NONE}, 0x0320F005, 0x0FFFFFFF, .V8, .A32, {}, {}} },
.DBG = { {.DBG, {.IMM_HINT, .NONE, .NONE, .NONE}, {.HINT_FIELD, .NONE, .NONE, .NONE}, 0x0320F0F0, 0x0FFFFFF0, .V7, .A32, {}, {}} },
.DBG = { {.DBG, {.IMM_HINT, .NONE, .NONE, .NONE}, {.DBG_OPTION, .NONE, .NONE, .NONE}, 0x0320F0F0, 0x0FFFFFF0, .V7, .A32, {}, {}} },
.HINT = { {.HINT, {.IMM_HINT, .NONE, .NONE, .NONE}, {.HINT_FIELD, .NONE, .NONE, .NONE}, 0x0320F000, 0x0FFFFF00, .V6K, .A32, {}, {}} },
// Memory barriers (ARMv7): 1111 0101 0111 1111 1111 0000 type imm4
@@ -1154,13 +1154,39 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{
.SWPB = { {.SWPB, {.GPR, .GPR, .GPR, .NONE}, {.RT_A32, .RM_A32, .RN_A32, .NONE}, 0x01400090, 0x0FF00FF0, .BASE, .A32, {deprecated=true}, {}} },
// RFE / SRS (return-from-exception / store return state)
.RFE = {
// 1111 100 P U 0 W 1 Rn 0000 1010 0000 0000
{.RFE, {.GPR, .NONE, .NONE, .NONE}, {.RN_A32, .NONE, .NONE, .NONE}, 0xF8100A00, 0xFE10FFFF, .V6, .A32, {cond_in_28=false}, {}},
// 1111 100 P U 0 W 1 Rn 0000 1010 0000 0000
.RFEDA = {
{.RFEDA, {.GPR, .NONE, .NONE, .NONE}, {.RN_A32_WB, .NONE, .NONE, .NONE}, 0xF8100A00, 0xFFF0FFFF, .V6, .A32, {cond_in_28=false}, {}},
{.RFEDA, {.GPR, .NONE, .NONE, .NONE}, {.RN_A32_WB, .NONE, .NONE, .NONE}, 0xF8300A00, 0xFFF0FFFF, .V6, .A32, {cond_in_28=false}, {}},
},
.SRS = {
// 1111 100 P U 1 W 0 1101 0000 0101 000 mode4
{.SRS, {.IMM, .NONE, .NONE, .NONE}, {.NONE, .NONE, .NONE, .NONE}, 0xF84D0500, 0xFE5FFFE0, .V6, .A32, {cond_in_28=false}, {}},
.RFEDB = {
{.RFEDB, {.GPR, .NONE, .NONE, .NONE}, {.RN_A32_WB, .NONE, .NONE, .NONE}, 0xF9100A00, 0xFFF0FFFF, .V6, .A32, {cond_in_28=false}, {}},
{.RFEDB, {.GPR, .NONE, .NONE, .NONE}, {.RN_A32_WB, .NONE, .NONE, .NONE}, 0xF9300A00, 0xFFF0FFFF, .V6, .A32, {cond_in_28=false}, {}},
},
.RFEIA = {
{.RFEIA, {.GPR, .NONE, .NONE, .NONE}, {.RN_A32_WB, .NONE, .NONE, .NONE}, 0xF8900A00, 0xFFF0FFFF, .V6, .A32, {cond_in_28=false}, {}},
{.RFEIA, {.GPR, .NONE, .NONE, .NONE}, {.RN_A32_WB, .NONE, .NONE, .NONE}, 0xF8B00A00, 0xFFF0FFFF, .V6, .A32, {cond_in_28=false}, {}},
},
.RFEIB = {
{.RFEIB, {.GPR, .NONE, .NONE, .NONE}, {.RN_A32_WB, .NONE, .NONE, .NONE}, 0xF9900A00, 0xFFF0FFFF, .V6, .A32, {cond_in_28=false}, {}},
{.RFEIB, {.GPR, .NONE, .NONE, .NONE}, {.RN_A32_WB, .NONE, .NONE, .NONE}, 0xF9B00A00, 0xFFF0FFFF, .V6, .A32, {cond_in_28=false}, {}},
},
// 1111 100 P U 1 W 0 1101 0000 0101 000 mode4
.SRSDA = {
{.SRSDA, {.GPR, .IMM, .NONE, .NONE}, {.IMPL_SP, .MODE_IMM5, .NONE, .NONE}, 0xF84D0500, 0xFFFFFFE0, .V6, .A32, {cond_in_28=false}, {}},
{.SRSDA, {.GPR, .IMM, .NONE, .NONE}, {.IMPL_SP, .MODE_IMM5, .NONE, .NONE}, 0xF86D0500, 0xFFFFFFE0, .V6, .A32, {cond_in_28=false}, {}},
},
.SRSDB = {
{.SRSDB, {.GPR, .IMM, .NONE, .NONE}, {.IMPL_SP, .MODE_IMM5, .NONE, .NONE}, 0xF94D0500, 0xFFFFFFE0, .V6, .A32, {cond_in_28=false}, {}},
{.SRSDB, {.GPR, .IMM, .NONE, .NONE}, {.IMPL_SP, .MODE_IMM5, .NONE, .NONE}, 0xF96D0500, 0xFFFFFFE0, .V6, .A32, {cond_in_28=false}, {}},
},
.SRSIA = {
{.SRSIA, {.GPR, .IMM, .NONE, .NONE}, {.IMPL_SP, .MODE_IMM5, .NONE, .NONE}, 0xF8CD0500, 0xFFFFFFE0, .V6, .A32, {cond_in_28=false}, {}},
{.SRSIA, {.GPR, .IMM, .NONE, .NONE}, {.IMPL_SP, .MODE_IMM5, .NONE, .NONE}, 0xF8ED0500, 0xFFFFFFE0, .V6, .A32, {cond_in_28=false}, {}},
},
.SRSIB = {
{.SRSIB, {.GPR, .IMM, .NONE, .NONE}, {.IMPL_SP, .MODE_IMM5, .NONE, .NONE}, 0xF9CD0500, 0xFFFFFFE0, .V6, .A32, {cond_in_28=false}, {}},
{.SRSIB, {.GPR, .IMM, .NONE, .NONE}, {.IMPL_SP, .MODE_IMM5, .NONE, .NONE}, 0xF9ED0500, 0xFFFFFFE0, .V6, .A32, {cond_in_28=false}, {}},
},
// =========================================================================
@@ -1605,8 +1631,8 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{
// VMRS / VMSR (access FPSCR + friends as GPR)
// VMRS: cond 1110 1111 0001 Rt 1010 0001 0000 (Rt=PC means transfer to APSR.NZCV)
.VMRS = { {.VMRS, {.GPR, .NONE, .NONE, .NONE}, {.RT_A32, .NONE, .NONE, .NONE}, 0x0EF10A10, 0x0FFF0FFF, .VFPV2, .A32, {}, {}} },
.VMSR = { {.VMSR, {.GPR, .NONE, .NONE, .NONE}, {.RT_A32, .NONE, .NONE, .NONE}, 0x0EE10A10, 0x0FFF0FFF, .VFPV2, .A32, {}, {}} },
.VMRS = { {.VMRS, {.GPR, .PSR_FIELD, .NONE, .NONE}, {.RT_A32, .VFP_SPEC_REG, .NONE, .NONE}, 0x0EF10A10, 0x0FF00FFF, .VFPV2, .A32, {}, {}} },
.VMSR = { {.VMSR, {.PSR_FIELD, .GPR, .NONE, .NONE}, {.VFP_SPEC_REG, .RT_A32, .NONE, .NONE}, 0x0EE10A10, 0x0FF00FFF, .VFPV2, .A32, {}, {}} },
// VLDR / VSTR (single / double): cond 1101 U D 0 1 Rn Vd 101 sz imm8
.VLDR = {
@@ -1803,12 +1829,36 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{
{.VAND, {.QPR, .QPR, .QPR, .NONE}, {.VD_Q, .VN_Q, .VM_Q, .NONE}, 0xEF000150, 0xFFB10F51, .MVE_INT, .T32, {thumb32=true, cond_in_28=false}, {}},
},
.VBIC = {
{.VBIC, {.DPR, .IMM, .NONE, .NONE}, {.VD_D, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800130, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VBIC, {.QPR, .IMM, .NONE, .NONE}, {.VD_Q, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800170, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VBIC, {.DPR, .IMM, .NONE, .NONE}, {.VD_D, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800330, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VBIC, {.QPR, .IMM, .NONE, .NONE}, {.VD_Q, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800370, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VBIC, {.DPR, .IMM, .NONE, .NONE}, {.VD_D, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800530, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VBIC, {.QPR, .IMM, .NONE, .NONE}, {.VD_Q, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800570, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VBIC, {.DPR, .IMM, .NONE, .NONE}, {.VD_D, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800730, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VBIC, {.QPR, .IMM, .NONE, .NONE}, {.VD_Q, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800770, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VBIC, {.DPR, .IMM, .NONE, .NONE}, {.VD_D, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800930, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I16, .NONE}},
{.VBIC, {.QPR, .IMM, .NONE, .NONE}, {.VD_Q, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800970, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I16, .NONE}},
{.VBIC, {.DPR, .IMM, .NONE, .NONE}, {.VD_D, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800B30, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I16, .NONE}},
{.VBIC, {.QPR, .IMM, .NONE, .NONE}, {.VD_Q, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800B70, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I16, .NONE}},
// VBIC D: 1111 0010 0100 Vn Vd 0001 N 0 M 1 Vm
{.VBIC, {.DPR, .DPR, .DPR, .NONE}, {.VD_D, .VN_D, .VM_D, .NONE}, 0xF2100110, 0xFFB00F10, .NEON, .A32, {cond_in_28=false}, {}},
{.VBIC, {.QPR, .QPR, .QPR, .NONE}, {.VD_Q, .VN_Q, .VM_Q, .NONE}, 0xF2100150, 0xFFB00F50, .NEON, .A32, {cond_in_28=false}, {}},
{.VBIC, {.QPR, .QPR, .QPR, .NONE}, {.VD_Q, .VN_Q, .VM_Q, .NONE}, 0xEF100150, 0xFFB10F51, .MVE_INT, .T32, {thumb32=true, cond_in_28=false}, {}},
},
.VORR = {
{.VORR, {.DPR, .IMM, .NONE, .NONE}, {.VD_D, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800110, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VORR, {.QPR, .IMM, .NONE, .NONE}, {.VD_Q, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800150, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VORR, {.DPR, .IMM, .NONE, .NONE}, {.VD_D, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800310, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VORR, {.QPR, .IMM, .NONE, .NONE}, {.VD_Q, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800350, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VORR, {.DPR, .IMM, .NONE, .NONE}, {.VD_D, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800510, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VORR, {.QPR, .IMM, .NONE, .NONE}, {.VD_Q, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800550, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VORR, {.DPR, .IMM, .NONE, .NONE}, {.VD_D, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800710, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VORR, {.QPR, .IMM, .NONE, .NONE}, {.VD_Q, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800750, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}},
{.VORR, {.DPR, .IMM, .NONE, .NONE}, {.VD_D, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800910, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I16, .NONE}},
{.VORR, {.QPR, .IMM, .NONE, .NONE}, {.VD_Q, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800950, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I16, .NONE}},
{.VORR, {.DPR, .IMM, .NONE, .NONE}, {.VD_D, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800B10, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I16, .NONE}},
{.VORR, {.QPR, .IMM, .NONE, .NONE}, {.VD_Q, .NEON_IMM8_ABCDEFGH, .NONE, .NONE}, 0xF2800B50, 0xFEB80FF0, .NEON, .A32, {cond_in_28=false}, {.I16, .NONE}},
{.VORR, {.DPR, .DPR, .DPR, .NONE}, {.VD_D, .VN_D, .VM_D, .NONE}, 0xF2200110, 0xFFB00F10, .NEON, .A32, {cond_in_28=false}, {}},
{.VORR, {.QPR, .QPR, .QPR, .NONE}, {.VD_Q, .VN_Q, .VM_Q, .NONE}, 0xF2200150, 0xFFB00F50, .NEON, .A32, {cond_in_28=false}, {}},
{.VORR, {.QPR, .QPR, .QPR, .NONE}, {.VD_Q, .VN_Q, .VM_Q, .NONE}, 0xEF200150, 0xFFB10F51, .MVE_INT, .T32, {thumb32=true, cond_in_28=false}, {}},

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ package rexcode_arm32_generated
import lib "../.."
@(rodata)
ENCODE_FORMS := [1663]lib.Encoding{
ENCODE_FORMS := [1701]lib.Encoding{
// .AND
{ .AND, {.GPR,.GPR,.IMM_MOD,.NONE}, {.RD,.RN_A32,.A32_IMM_MOD,.NONE}, 0x02000000, 0x0FE00000, .BASE, .A32, {}, {.NONE,.NONE} },
{ .AND, {.GPR,.GPR,.GPR_SHIFTED,.NONE}, {.RD,.RN_A32,.RM_A32,.NONE}, 0x00000000, 0x0FE00010, .BASE, .A32, {}, {.NONE,.NONE} },
@@ -549,12 +549,12 @@ ENCODE_FORMS := [1663]lib.Encoding{
{ .MSR, {.PSR_FIELD,.GPR,.NONE,.NONE}, {.PSR_FIELD_MASK,.RM_A32,.NONE,.NONE}, 0x0120F000, 0x0FB0FFF0, .BASE, .A32, {}, {.NONE,.NONE} },
{ .MSR, {.PSR_FIELD,.GPR,.NONE,.NONE}, {.PSR_FIELD_MASK,.RN_T32,.NONE,.NONE}, 0xF3808000, 0xFFF0F0FF, .V6T2, .T32, {thumb32=true}, {.NONE,.NONE} },
// .MRS
{ .MRS, {.GPR,.PSR_FIELD,.NONE,.NONE}, {.RD,.NONE,.NONE,.NONE}, 0x010F0000, 0x0FBF0FFF, .BASE, .A32, {}, {.NONE,.NONE} },
{ .MRS, {.GPR,.PSR_FIELD,.NONE,.NONE}, {.RD,.MRS_SPEC_REG,.NONE,.NONE}, 0x010F0000, 0x0FBF0FFF, .BASE, .A32, {}, {.NONE,.NONE} },
{ .MRS, {.GPR,.PSR_FIELD,.NONE,.NONE}, {.RD_T32,.NONE,.NONE,.NONE}, 0xF3EF8000, 0xFFFFF0FF, .V6T2, .T32, {thumb32=true}, {.NONE,.NONE} },
// .CPS
{ .CPS, {.IMM_IFLAGS,.NONE,.NONE,.NONE}, {.CPS_IFLAGS,.NONE,.NONE,.NONE}, 0xF1000000, 0xFFF1FE20, .V6, .A32, {}, {.NONE,.NONE} },
// .SETEND
{ .SETEND, {.IMM_ENDIAN,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0xF1010000, 0xFFFFFDFF, .V6, .A32, {deprecated=true}, {.NONE,.NONE} },
{ .SETEND, {.IMM_ENDIAN,.NONE,.NONE,.NONE}, {.SETEND_ENDIAN,.NONE,.NONE,.NONE}, 0xF1010000, 0xFFFFFDFF, .V6, .A32, {deprecated=true}, {.NONE,.NONE} },
// .NOP
{ .NOP, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x0320F000, 0x0FFFFFFF, .V6K, .A32, {}, {.NONE,.NONE} },
{ .NOP, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x0000BF00, 0x0000FFFF, .V6T2, .T32, {}, {.NONE,.NONE} },
@@ -578,7 +578,7 @@ ENCODE_FORMS := [1663]lib.Encoding{
// .SEVL
{ .SEVL, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x0320F005, 0x0FFFFFFF, .V8, .A32, {}, {.NONE,.NONE} },
// .DBG
{ .DBG, {.IMM_HINT,.NONE,.NONE,.NONE}, {.HINT_FIELD,.NONE,.NONE,.NONE}, 0x0320F0F0, 0x0FFFFFF0, .V7, .A32, {}, {.NONE,.NONE} },
{ .DBG, {.IMM_HINT,.NONE,.NONE,.NONE}, {.DBG_OPTION,.NONE,.NONE,.NONE}, 0x0320F0F0, 0x0FFFFFF0, .V7, .A32, {}, {.NONE,.NONE} },
// .HINT
{ .HINT, {.IMM_HINT,.NONE,.NONE,.NONE}, {.HINT_FIELD,.NONE,.NONE,.NONE}, 0x0320F000, 0x0FFFFF00, .V6K, .A32, {}, {.NONE,.NONE} },
// .DMB
@@ -834,10 +834,30 @@ ENCODE_FORMS := [1663]lib.Encoding{
{ .SWP, {.GPR,.GPR,.GPR,.NONE}, {.RT_A32,.RM_A32,.RN_A32,.NONE}, 0x01000090, 0x0FF00FF0, .BASE, .A32, {deprecated=true}, {.NONE,.NONE} },
// .SWPB
{ .SWPB, {.GPR,.GPR,.GPR,.NONE}, {.RT_A32,.RM_A32,.RN_A32,.NONE}, 0x01400090, 0x0FF00FF0, .BASE, .A32, {deprecated=true}, {.NONE,.NONE} },
// .RFE
{ .RFE, {.GPR,.NONE,.NONE,.NONE}, {.RN_A32,.NONE,.NONE,.NONE}, 0xF8100A00, 0xFE10FFFF, .V6, .A32, {}, {.NONE,.NONE} },
// .SRS
{ .SRS, {.IMM,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0xF84D0500, 0xFE5FFFE0, .V6, .A32, {}, {.NONE,.NONE} },
// .RFEDA
{ .RFEDA, {.GPR,.NONE,.NONE,.NONE}, {.RN_A32_WB,.NONE,.NONE,.NONE}, 0xF8100A00, 0xFFF0FFFF, .V6, .A32, {}, {.NONE,.NONE} },
{ .RFEDA, {.GPR,.NONE,.NONE,.NONE}, {.RN_A32_WB,.NONE,.NONE,.NONE}, 0xF8300A00, 0xFFF0FFFF, .V6, .A32, {}, {.NONE,.NONE} },
// .RFEDB
{ .RFEDB, {.GPR,.NONE,.NONE,.NONE}, {.RN_A32_WB,.NONE,.NONE,.NONE}, 0xF9100A00, 0xFFF0FFFF, .V6, .A32, {}, {.NONE,.NONE} },
{ .RFEDB, {.GPR,.NONE,.NONE,.NONE}, {.RN_A32_WB,.NONE,.NONE,.NONE}, 0xF9300A00, 0xFFF0FFFF, .V6, .A32, {}, {.NONE,.NONE} },
// .RFEIA
{ .RFEIA, {.GPR,.NONE,.NONE,.NONE}, {.RN_A32_WB,.NONE,.NONE,.NONE}, 0xF8900A00, 0xFFF0FFFF, .V6, .A32, {}, {.NONE,.NONE} },
{ .RFEIA, {.GPR,.NONE,.NONE,.NONE}, {.RN_A32_WB,.NONE,.NONE,.NONE}, 0xF8B00A00, 0xFFF0FFFF, .V6, .A32, {}, {.NONE,.NONE} },
// .RFEIB
{ .RFEIB, {.GPR,.NONE,.NONE,.NONE}, {.RN_A32_WB,.NONE,.NONE,.NONE}, 0xF9900A00, 0xFFF0FFFF, .V6, .A32, {}, {.NONE,.NONE} },
{ .RFEIB, {.GPR,.NONE,.NONE,.NONE}, {.RN_A32_WB,.NONE,.NONE,.NONE}, 0xF9B00A00, 0xFFF0FFFF, .V6, .A32, {}, {.NONE,.NONE} },
// .SRSDA
{ .SRSDA, {.GPR,.IMM,.NONE,.NONE}, {.IMPL_SP,.MODE_IMM5,.NONE,.NONE}, 0xF84D0500, 0xFFFFFFE0, .V6, .A32, {}, {.NONE,.NONE} },
{ .SRSDA, {.GPR,.IMM,.NONE,.NONE}, {.IMPL_SP,.MODE_IMM5,.NONE,.NONE}, 0xF86D0500, 0xFFFFFFE0, .V6, .A32, {}, {.NONE,.NONE} },
// .SRSDB
{ .SRSDB, {.GPR,.IMM,.NONE,.NONE}, {.IMPL_SP,.MODE_IMM5,.NONE,.NONE}, 0xF94D0500, 0xFFFFFFE0, .V6, .A32, {}, {.NONE,.NONE} },
{ .SRSDB, {.GPR,.IMM,.NONE,.NONE}, {.IMPL_SP,.MODE_IMM5,.NONE,.NONE}, 0xF96D0500, 0xFFFFFFE0, .V6, .A32, {}, {.NONE,.NONE} },
// .SRSIA
{ .SRSIA, {.GPR,.IMM,.NONE,.NONE}, {.IMPL_SP,.MODE_IMM5,.NONE,.NONE}, 0xF8CD0500, 0xFFFFFFE0, .V6, .A32, {}, {.NONE,.NONE} },
{ .SRSIA, {.GPR,.IMM,.NONE,.NONE}, {.IMPL_SP,.MODE_IMM5,.NONE,.NONE}, 0xF8ED0500, 0xFFFFFFE0, .V6, .A32, {}, {.NONE,.NONE} },
// .SRSIB
{ .SRSIB, {.GPR,.IMM,.NONE,.NONE}, {.IMPL_SP,.MODE_IMM5,.NONE,.NONE}, 0xF9CD0500, 0xFFFFFFE0, .V6, .A32, {}, {.NONE,.NONE} },
{ .SRSIB, {.GPR,.IMM,.NONE,.NONE}, {.IMPL_SP,.MODE_IMM5,.NONE,.NONE}, 0xF9ED0500, 0xFFFFFFE0, .V6, .A32, {}, {.NONE,.NONE} },
// .CDP
{ .CDP, {.COPROC_NUM,.IMM_COPROC_OP,.COPROC_REG,.COPROC_REG}, {.COPROC_NUM_FIELD,.COPROC_OPC1_FIELD,.COPROC_CRN_FIELD,.COPROC_CRM_FIELD}, 0x0E000000, 0x0F000010, .BASE, .A32, {}, {.NONE,.NONE} },
// .CDP2
@@ -1147,9 +1167,9 @@ ENCODE_FORMS := [1663]lib.Encoding{
{ .VMOV, {.DPR_ELEM,.GPR,.NONE,.NONE}, {.VMOV_LANE_16,.RT_A32,.NONE,.NONE}, 0x0E000B30, 0x0FD00F3F, .VFPV2, .A32, {}, {.SZ16,.NONE} },
{ .VMOV, {.DPR_ELEM,.GPR,.NONE,.NONE}, {.VMOV_LANE_32,.RT_A32,.NONE,.NONE}, 0x0E000B10, 0x0FD00F7F, .VFPV2, .A32, {}, {.SZ32,.NONE} },
// .VMRS
{ .VMRS, {.GPR,.NONE,.NONE,.NONE}, {.RT_A32,.NONE,.NONE,.NONE}, 0x0EF10A10, 0x0FFF0FFF, .VFPV2, .A32, {}, {.NONE,.NONE} },
{ .VMRS, {.GPR,.PSR_FIELD,.NONE,.NONE}, {.RT_A32,.VFP_SPEC_REG,.NONE,.NONE}, 0x0EF10A10, 0x0FF00FFF, .VFPV2, .A32, {}, {.NONE,.NONE} },
// .VMSR
{ .VMSR, {.GPR,.NONE,.NONE,.NONE}, {.RT_A32,.NONE,.NONE,.NONE}, 0x0EE10A10, 0x0FFF0FFF, .VFPV2, .A32, {}, {.NONE,.NONE} },
{ .VMSR, {.PSR_FIELD,.GPR,.NONE,.NONE}, {.VFP_SPEC_REG,.RT_A32,.NONE,.NONE}, 0x0EE10A10, 0x0FF00FFF, .VFPV2, .A32, {}, {.NONE,.NONE} },
// .VLDR
{ .VLDR, {.SPR,.MEM,.NONE,.NONE}, {.VD_S,.MEM_IMM8_SCALED4,.NONE,.NONE}, 0x0D100A00, 0x0F300F00, .VFPV2, .A32, {}, {.NONE,.NONE} },
{ .VLDR, {.DPR,.MEM,.NONE,.NONE}, {.VD_D,.MEM_IMM8_SCALED4,.NONE,.NONE}, 0x0D100B00, 0x0F300F00, .VFPV2, .A32, {}, {.NONE,.NONE} },
@@ -1404,10 +1424,34 @@ ENCODE_FORMS := [1663]lib.Encoding{
{ .VAND, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xF2000150, 0xFFB00F50, .NEON, .A32, {}, {.NONE,.NONE} },
{ .VAND, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xEF000150, 0xFFB10F51, .MVE_INT, .T32, {thumb32=true}, {.NONE,.NONE} },
// .VBIC
{ .VBIC, {.DPR,.IMM,.NONE,.NONE}, {.VD_D,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800130, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VBIC, {.QPR,.IMM,.NONE,.NONE}, {.VD_Q,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800170, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VBIC, {.DPR,.IMM,.NONE,.NONE}, {.VD_D,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800330, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VBIC, {.QPR,.IMM,.NONE,.NONE}, {.VD_Q,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800370, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VBIC, {.DPR,.IMM,.NONE,.NONE}, {.VD_D,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800530, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VBIC, {.QPR,.IMM,.NONE,.NONE}, {.VD_Q,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800570, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VBIC, {.DPR,.IMM,.NONE,.NONE}, {.VD_D,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800730, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VBIC, {.QPR,.IMM,.NONE,.NONE}, {.VD_Q,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800770, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VBIC, {.DPR,.IMM,.NONE,.NONE}, {.VD_D,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800930, 0xFEB80FF0, .NEON, .A32, {}, {.I16,.NONE} },
{ .VBIC, {.QPR,.IMM,.NONE,.NONE}, {.VD_Q,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800970, 0xFEB80FF0, .NEON, .A32, {}, {.I16,.NONE} },
{ .VBIC, {.DPR,.IMM,.NONE,.NONE}, {.VD_D,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800B30, 0xFEB80FF0, .NEON, .A32, {}, {.I16,.NONE} },
{ .VBIC, {.QPR,.IMM,.NONE,.NONE}, {.VD_Q,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800B70, 0xFEB80FF0, .NEON, .A32, {}, {.I16,.NONE} },
{ .VBIC, {.DPR,.DPR,.DPR,.NONE}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xF2100110, 0xFFB00F10, .NEON, .A32, {}, {.NONE,.NONE} },
{ .VBIC, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xF2100150, 0xFFB00F50, .NEON, .A32, {}, {.NONE,.NONE} },
{ .VBIC, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xEF100150, 0xFFB10F51, .MVE_INT, .T32, {thumb32=true}, {.NONE,.NONE} },
// .VORR
{ .VORR, {.DPR,.IMM,.NONE,.NONE}, {.VD_D,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800110, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VORR, {.QPR,.IMM,.NONE,.NONE}, {.VD_Q,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800150, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VORR, {.DPR,.IMM,.NONE,.NONE}, {.VD_D,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800310, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VORR, {.QPR,.IMM,.NONE,.NONE}, {.VD_Q,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800350, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VORR, {.DPR,.IMM,.NONE,.NONE}, {.VD_D,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800510, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VORR, {.QPR,.IMM,.NONE,.NONE}, {.VD_Q,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800550, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VORR, {.DPR,.IMM,.NONE,.NONE}, {.VD_D,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800710, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VORR, {.QPR,.IMM,.NONE,.NONE}, {.VD_Q,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800750, 0xFEB80FF0, .NEON, .A32, {}, {.I32,.NONE} },
{ .VORR, {.DPR,.IMM,.NONE,.NONE}, {.VD_D,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800910, 0xFEB80FF0, .NEON, .A32, {}, {.I16,.NONE} },
{ .VORR, {.QPR,.IMM,.NONE,.NONE}, {.VD_Q,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800950, 0xFEB80FF0, .NEON, .A32, {}, {.I16,.NONE} },
{ .VORR, {.DPR,.IMM,.NONE,.NONE}, {.VD_D,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800B10, 0xFEB80FF0, .NEON, .A32, {}, {.I16,.NONE} },
{ .VORR, {.QPR,.IMM,.NONE,.NONE}, {.VD_Q,.NEON_IMM8_ABCDEFGH,.NONE,.NONE}, 0xF2800B50, 0xFEB80FF0, .NEON, .A32, {}, {.I16,.NONE} },
{ .VORR, {.DPR,.DPR,.DPR,.NONE}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xF2200110, 0xFFB00F10, .NEON, .A32, {}, {.NONE,.NONE} },
{ .VORR, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xF2200150, 0xFFB00F50, .NEON, .A32, {}, {.NONE,.NONE} },
{ .VORR, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xEF200150, 0xFFB10F51, .MVE_INT, .T32, {thumb32=true}, {.NONE,.NONE} },
@@ -2495,354 +2539,360 @@ ENCODE_RUNS := [lib.Mnemonic]lib.Encode_Run{
.POP = { 585, 3},
.SWP = { 588, 1},
.SWPB = { 589, 1},
.RFE = { 590, 1},
.SRS = { 591, 1},
.CDP = { 592, 1},
.CDP2 = { 593, 1},
.MCR = { 594, 1},
.MCR2 = { 595, 1},
.MRC = { 596, 1},
.MRC2 = { 597, 1},
.MCRR = { 598, 1},
.MCRR2 = { 599, 1},
.MRRC = { 600, 1},
.MRRC2 = { 601, 1},
.LDC = { 602, 1},
.LDC2 = { 603, 1},
.STC = { 604, 1},
.STC2 = { 605, 1},
.CRC32B = { 606, 1},
.CRC32H = { 607, 1},
.CRC32W = { 608, 1},
.CRC32CB = { 609, 1},
.CRC32CH = { 610, 1},
.CRC32CW = { 611, 1},
.VADD = { 612, 18},
.VSUB = { 630, 18},
.VMUL = { 648, 22},
.VDIV = { 670, 3},
.VMLA = { 673, 16},
.VMLS = { 689, 15},
.VNMUL = { 704, 2},
.VNMLA = { 706, 2},
.VNMLS = { 708, 2},
.VFMA = { 710, 8},
.VFMS = { 718, 6},
.VFNMA = { 724, 3},
.VFNMS = { 727, 3},
.VABS = { 730, 12},
.VNEG = { 742, 12},
.VSQRT = { 754, 3},
.VCMP = { 757, 8},
.VCMPE = { 765, 4},
.VCVT = { 769, 35},
.VCVTB = { 804, 2},
.VCVTT = { 806, 2},
.VCVTA = { 808, 2},
.VCVTN = { 810, 2},
.VCVTP = { 812, 2},
.VCVTM = { 814, 2},
.VCVTR = { 816, 4},
.VMOV = { 820, 33},
.VMRS = { 853, 1},
.VMSR = { 854, 1},
.VLDR = { 855, 2},
.VSTR = { 857, 2},
.VLDM = { 859, 2},
.VSTM = { 861, 2},
.VPUSH = { 863, 2},
.VPOP = { 865, 2},
.VSEL = { 867, 2},
.VMAXNM = { 869, 2},
.VMINNM = { 871, 2},
.VRINTA = { 873, 3},
.VRINTN = { 876, 3},
.VRINTP = { 879, 3},
.VRINTM = { 882, 3},
.VRINTR = { 885, 2},
.VRINTZ = { 887, 3},
.VRINTX = { 890, 3},
.VADDL = { 893, 6},
.VADDW = { 899, 6},
.VSUBL = { 905, 6},
.VSUBW = { 911, 6},
.VHADD = { 917, 9},
.VHSUB = { 926, 9},
.VRHADD = { 935, 3},
.VQADD = { 938, 11},
.VQSUB = { 949, 11},
.VMULL = { 960, 11},
.VMLAL = { 971, 10},
.VMLSL = { 981, 10},
.VQDMULL = { 991, 4},
.VQDMLAL = { 995, 4},
.VQDMLSL = { 999, 4},
.VQDMULH = { 1003, 8},
.VQRDMULH = { 1011, 8},
.VQRDMLAH = { 1019, 8},
.VQRDMLSH = { 1027, 8},
.VABA = { 1035, 8},
.VABAL = { 1043, 6},
.VABD = { 1049, 10},
.VABDL = { 1059, 6},
.VAND = { 1065, 3},
.VBIC = { 1068, 3},
.VORR = { 1071, 3},
.VORN = { 1074, 3},
.VEOR = { 1077, 3},
.VBSL = { 1080, 2},
.VBIT = { 1082, 2},
.VBIF = { 1084, 2},
.VMVN = { 1086, 13},
.VMOVN = { 1099, 3},
.VQMOVN = { 1102, 6},
.VQMOVUN = { 1108, 3},
.VMOVL = { 1111, 6},
.VTST = { 1117, 6},
.VCEQ = { 1123, 14},
.VCGE = { 1137, 16},
.VCGT = { 1153, 16},
.VCLE = { 1169, 18},
.VCLT = { 1187, 18},
.VACGE = { 1205, 2},
.VACGT = { 1207, 2},
.VACLE = { 1209, 2},
.VACLT = { 1211, 2},
.VMAX = { 1213, 13},
.VMIN = { 1226, 13},
.VPMAX = { 1239, 5},
.VPMIN = { 1244, 5},
.VPADD = { 1249, 5},
.VPADDL = { 1254, 6},
.VPADAL = { 1260, 4},
.VRECPE = { 1264, 4},
.VRECPS = { 1268, 2},
.VRSQRTE = { 1270, 4},
.VRSQRTS = { 1274, 2},
.VSHL = { 1276, 9},
.VSHR = { 1285, 3},
.VSRA = { 1288, 3},
.VRSHL = { 1291, 5},
.VRSHR = { 1296, 3},
.VRSRA = { 1299, 2},
.VSLI = { 1301, 2},
.VSRI = { 1303, 2},
.VQSHL = { 1305, 7},
.VQSHRN = { 1312, 1},
.VQSHRUN = { 1313, 1},
.VQRSHL = { 1314, 16},
.VQRSHRN = { 1330, 1},
.VQRSHRUN = { 1331, 1},
.VSHRN = { 1332, 1},
.VRSHRN = { 1333, 1},
.VSHLL = { 1334, 4},
.VCLS = { 1338, 6},
.VCLZ = { 1344, 6},
.VCNT = { 1350, 2},
.VREV16 = { 1352, 2},
.VREV32 = { 1354, 4},
.VREV64 = { 1358, 6},
.VEXT = { 1364, 2},
.VTBL = { 1366, 4},
.VTBX = { 1370, 4},
.VTRN = { 1374, 6},
.VUZP = { 1380, 5},
.VZIP = { 1385, 5},
.VDUP = { 1390, 5},
.VSWP = { 1395, 2},
.VLD1 = { 1397, 8},
.VLD2 = { 1405, 6},
.VLD3 = { 1411, 5},
.VLD4 = { 1416, 5},
.VST1 = { 1421, 7},
.VST2 = { 1428, 6},
.VST3 = { 1434, 5},
.VST4 = { 1439, 5},
.AESE = { 1444, 1},
.AESD = { 1445, 1},
.AESMC = { 1446, 1},
.AESIMC = { 1447, 1},
.SHA1H = { 1448, 1},
.SHA1SU0 = { 1449, 1},
.SHA1SU1 = { 1450, 1},
.SHA1C = { 1451, 1},
.SHA1M = { 1452, 1},
.SHA1P = { 1453, 1},
.SHA256H = { 1454, 1},
.SHA256H2 = { 1455, 1},
.SHA256SU0 = { 1456, 1},
.SHA256SU1 = { 1457, 1},
.VJCVT = { 1458, 1},
.VSDOT = { 1459, 4},
.VUDOT = { 1463, 4},
.VDOT = { 1467, 2},
.VMMLA = { 1469, 1},
.VFMAL = { 1470, 2},
.VFMSL = { 1472, 2},
.VCMLA = { 1474, 5},
.VCADD = { 1479, 2},
.VSMMLA = { 1481, 1},
.VUMMLA = { 1482, 1},
.VUSMMLA = { 1483, 1},
.VSUDOT = { 1484, 2},
.VUSDOT = { 1486, 4},
.VQABS = { 1490, 1},
.VQNEG = { 1491, 1},
.VMOVX = { 1492, 1},
.VINS = { 1493, 1},
.VLD2R = { 1494, 1},
.VLD3R = { 1495, 1},
.VLD4R = { 1496, 1},
.IT = { 1497, 1},
.TT = { 1498, 1},
.TTT = { 1499, 1},
.TTA = { 1500, 1},
.TTAT = { 1501, 1},
.SG = { 1502, 1},
.BXNS = { 1503, 1},
.BLXNS = { 1504, 1},
.PAC = { 1505, 1},
.PACBTI = { 1506, 1},
.AUT = { 1507, 1},
.AUTG = { 1508, 1},
.BTI = { 1509, 1},
.WLS = { 1510, 1},
.WLSTP = { 1511, 1},
.DLS = { 1512, 1},
.DLSTP = { 1513, 1},
.LE = { 1514, 1},
.LETP = { 1515, 1},
.LCTP = { 1516, 1},
.BF = { 1517, 1},
.BFX = { 1518, 1},
.BFL = { 1519, 1},
.BFLX = { 1520, 1},
.BFCSEL = { 1521, 1},
.CX1 = { 1522, 1},
.CX1A = { 1523, 1},
.CX1D = { 1524, 1},
.CX1DA = { 1525, 1},
.CX2 = { 1526, 1},
.CX2A = { 1527, 1},
.CX2D = { 1528, 1},
.CX2DA = { 1529, 1},
.CX3 = { 1530, 1},
.CX3A = { 1531, 1},
.CX3D = { 1532, 1},
.CX3DA = { 1533, 1},
.VCX1 = { 1534, 2},
.VCX1A = { 1536, 2},
.VCX2 = { 1538, 2},
.VCX2A = { 1540, 2},
.VCX3 = { 1542, 2},
.VCX3A = { 1544, 2},
.VPT = { 1546, 1},
.VPST = { 1547, 1},
.VPSEL = { 1548, 1},
.VPNOT = { 1549, 1},
.VCTP = { 1550, 1},
.VADDV = { 1551, 1},
.VADDVA = { 1552, 1},
.VADDLV = { 1553, 1},
.VADDLVA = { 1554, 1},
.VMAXV = { 1555, 1},
.VMAXAV = { 1556, 1},
.VMINV = { 1557, 1},
.VMINAV = { 1558, 1},
.VMAXNMV = { 1559, 1},
.VMAXNMAV = { 1560, 1},
.VMINNMV = { 1561, 1},
.VMINNMAV = { 1562, 1},
.VABAV = { 1563, 1},
.VMLADAV = { 1564, 1},
.VMLADAVA = { 1565, 1},
.VMLADAVX = { 1566, 1},
.VMLADAVAX = { 1567, 1},
.VMLALDAV = { 1568, 1},
.VMLALDAVA = { 1569, 1},
.VMLALDAVX = { 1570, 1},
.VMLALDAVAX = { 1571, 1},
.VMLSDAV = { 1572, 1},
.VMLSDAVA = { 1573, 1},
.VMLSDAVX = { 1574, 1},
.VMLSDAVAX = { 1575, 1},
.VMLSLDAV = { 1576, 1},
.VMLSLDAVA = { 1577, 1},
.VMLSLDAVX = { 1578, 1},
.VMLSLDAVAX = { 1579, 1},
.VRMLALDAVH = { 1580, 1},
.VRMLALDAVHA = { 1581, 1},
.VRMLALDAVHX = { 1582, 1},
.VRMLALDAVHAX = { 1583, 1},
.VRMLSLDAVH = { 1584, 1},
.VRMLSLDAVHA = { 1585, 1},
.VRMLSLDAVHX = { 1586, 1},
.VRMLSLDAVHAX = { 1587, 1},
.VMLAV = { 1588, 1},
.VMLAVA = { 1589, 1},
.VMLSV = { 1590, 1},
.VMLSVA = { 1591, 1},
.VCMUL = { 1592, 1},
.VHCADD = { 1593, 2},
.VBRSR = { 1595, 1},
.VSHLC = { 1596, 1},
.VDDUP = { 1597, 1},
.VIDUP = { 1598, 1},
.VDWDUP = { 1599, 1},
.VIWDUP = { 1600, 1},
.VMOVNB = { 1601, 1},
.VMOVNT = { 1602, 1},
.VQMOVNB = { 1603, 1},
.VQMOVNT = { 1604, 1},
.VQMOVUNB = { 1605, 1},
.VQMOVUNT = { 1606, 1},
.VSHLLB = { 1607, 1},
.VSHLLT = { 1608, 1},
.VMULLB = { 1609, 1},
.VMULLT = { 1610, 1},
.VMLALB = { 1611, 1},
.VMLALT = { 1612, 1},
.VMLSLB = { 1613, 1},
.VMLSLT = { 1614, 1},
.VSHRNB = { 1615, 1},
.VSHRNT = { 1616, 1},
.VRSHRNB = { 1617, 1},
.VRSHRNT = { 1618, 1},
.VQSHRNB = { 1619, 1},
.VQSHRNT = { 1620, 1},
.VQRSHRNB = { 1621, 1},
.VQRSHRNT = { 1622, 1},
.VQSHRUNB = { 1623, 1},
.VQSHRUNT = { 1624, 1},
.VQRSHRUNB = { 1625, 1},
.VQRSHRUNT = { 1626, 1},
.VQDMLADH = { 1627, 1},
.VQDMLADHX = { 1628, 1},
.VQDMLSDH = { 1629, 1},
.VQDMLSDHX = { 1630, 1},
.VQRDMLADH = { 1631, 1},
.VQRDMLADHX = { 1632, 1},
.VQRDMLSDH = { 1633, 1},
.VQRDMLSDHX = { 1634, 1},
.VLDRB = { 1635, 2},
.VLDRH = { 1637, 2},
.VLDRW = { 1639, 2},
.VLDRD = { 1641, 2},
.VSTRB = { 1643, 2},
.VSTRH = { 1645, 2},
.VSTRW = { 1647, 2},
.VSTRD = { 1649, 2},
.VLD20 = { 1651, 1},
.VLD21 = { 1652, 1},
.VLD40 = { 1653, 1},
.VLD41 = { 1654, 1},
.VLD42 = { 1655, 1},
.VLD43 = { 1656, 1},
.VST20 = { 1657, 1},
.VST21 = { 1658, 1},
.VST40 = { 1659, 1},
.VST41 = { 1660, 1},
.VST42 = { 1661, 1},
.VST43 = { 1662, 1},
._COUNT = { 1663, 0},
.RFEDA = { 590, 2},
.RFEDB = { 592, 2},
.RFEIA = { 594, 2},
.RFEIB = { 596, 2},
.SRSDA = { 598, 2},
.SRSDB = { 600, 2},
.SRSIA = { 602, 2},
.SRSIB = { 604, 2},
.CDP = { 606, 1},
.CDP2 = { 607, 1},
.MCR = { 608, 1},
.MCR2 = { 609, 1},
.MRC = { 610, 1},
.MRC2 = { 611, 1},
.MCRR = { 612, 1},
.MCRR2 = { 613, 1},
.MRRC = { 614, 1},
.MRRC2 = { 615, 1},
.LDC = { 616, 1},
.LDC2 = { 617, 1},
.STC = { 618, 1},
.STC2 = { 619, 1},
.CRC32B = { 620, 1},
.CRC32H = { 621, 1},
.CRC32W = { 622, 1},
.CRC32CB = { 623, 1},
.CRC32CH = { 624, 1},
.CRC32CW = { 625, 1},
.VADD = { 626, 18},
.VSUB = { 644, 18},
.VMUL = { 662, 22},
.VDIV = { 684, 3},
.VMLA = { 687, 16},
.VMLS = { 703, 15},
.VNMUL = { 718, 2},
.VNMLA = { 720, 2},
.VNMLS = { 722, 2},
.VFMA = { 724, 8},
.VFMS = { 732, 6},
.VFNMA = { 738, 3},
.VFNMS = { 741, 3},
.VABS = { 744, 12},
.VNEG = { 756, 12},
.VSQRT = { 768, 3},
.VCMP = { 771, 8},
.VCMPE = { 779, 4},
.VCVT = { 783, 35},
.VCVTB = { 818, 2},
.VCVTT = { 820, 2},
.VCVTA = { 822, 2},
.VCVTN = { 824, 2},
.VCVTP = { 826, 2},
.VCVTM = { 828, 2},
.VCVTR = { 830, 4},
.VMOV = { 834, 33},
.VMRS = { 867, 1},
.VMSR = { 868, 1},
.VLDR = { 869, 2},
.VSTR = { 871, 2},
.VLDM = { 873, 2},
.VSTM = { 875, 2},
.VPUSH = { 877, 2},
.VPOP = { 879, 2},
.VSEL = { 881, 2},
.VMAXNM = { 883, 2},
.VMINNM = { 885, 2},
.VRINTA = { 887, 3},
.VRINTN = { 890, 3},
.VRINTP = { 893, 3},
.VRINTM = { 896, 3},
.VRINTR = { 899, 2},
.VRINTZ = { 901, 3},
.VRINTX = { 904, 3},
.VADDL = { 907, 6},
.VADDW = { 913, 6},
.VSUBL = { 919, 6},
.VSUBW = { 925, 6},
.VHADD = { 931, 9},
.VHSUB = { 940, 9},
.VRHADD = { 949, 3},
.VQADD = { 952, 11},
.VQSUB = { 963, 11},
.VMULL = { 974, 11},
.VMLAL = { 985, 10},
.VMLSL = { 995, 10},
.VQDMULL = { 1005, 4},
.VQDMLAL = { 1009, 4},
.VQDMLSL = { 1013, 4},
.VQDMULH = { 1017, 8},
.VQRDMULH = { 1025, 8},
.VQRDMLAH = { 1033, 8},
.VQRDMLSH = { 1041, 8},
.VABA = { 1049, 8},
.VABAL = { 1057, 6},
.VABD = { 1063, 10},
.VABDL = { 1073, 6},
.VAND = { 1079, 3},
.VBIC = { 1082, 15},
.VORR = { 1097, 15},
.VORN = { 1112, 3},
.VEOR = { 1115, 3},
.VBSL = { 1118, 2},
.VBIT = { 1120, 2},
.VBIF = { 1122, 2},
.VMVN = { 1124, 13},
.VMOVN = { 1137, 3},
.VQMOVN = { 1140, 6},
.VQMOVUN = { 1146, 3},
.VMOVL = { 1149, 6},
.VTST = { 1155, 6},
.VCEQ = { 1161, 14},
.VCGE = { 1175, 16},
.VCGT = { 1191, 16},
.VCLE = { 1207, 18},
.VCLT = { 1225, 18},
.VACGE = { 1243, 2},
.VACGT = { 1245, 2},
.VACLE = { 1247, 2},
.VACLT = { 1249, 2},
.VMAX = { 1251, 13},
.VMIN = { 1264, 13},
.VPMAX = { 1277, 5},
.VPMIN = { 1282, 5},
.VPADD = { 1287, 5},
.VPADDL = { 1292, 6},
.VPADAL = { 1298, 4},
.VRECPE = { 1302, 4},
.VRECPS = { 1306, 2},
.VRSQRTE = { 1308, 4},
.VRSQRTS = { 1312, 2},
.VSHL = { 1314, 9},
.VSHR = { 1323, 3},
.VSRA = { 1326, 3},
.VRSHL = { 1329, 5},
.VRSHR = { 1334, 3},
.VRSRA = { 1337, 2},
.VSLI = { 1339, 2},
.VSRI = { 1341, 2},
.VQSHL = { 1343, 7},
.VQSHRN = { 1350, 1},
.VQSHRUN = { 1351, 1},
.VQRSHL = { 1352, 16},
.VQRSHRN = { 1368, 1},
.VQRSHRUN = { 1369, 1},
.VSHRN = { 1370, 1},
.VRSHRN = { 1371, 1},
.VSHLL = { 1372, 4},
.VCLS = { 1376, 6},
.VCLZ = { 1382, 6},
.VCNT = { 1388, 2},
.VREV16 = { 1390, 2},
.VREV32 = { 1392, 4},
.VREV64 = { 1396, 6},
.VEXT = { 1402, 2},
.VTBL = { 1404, 4},
.VTBX = { 1408, 4},
.VTRN = { 1412, 6},
.VUZP = { 1418, 5},
.VZIP = { 1423, 5},
.VDUP = { 1428, 5},
.VSWP = { 1433, 2},
.VLD1 = { 1435, 8},
.VLD2 = { 1443, 6},
.VLD3 = { 1449, 5},
.VLD4 = { 1454, 5},
.VST1 = { 1459, 7},
.VST2 = { 1466, 6},
.VST3 = { 1472, 5},
.VST4 = { 1477, 5},
.AESE = { 1482, 1},
.AESD = { 1483, 1},
.AESMC = { 1484, 1},
.AESIMC = { 1485, 1},
.SHA1H = { 1486, 1},
.SHA1SU0 = { 1487, 1},
.SHA1SU1 = { 1488, 1},
.SHA1C = { 1489, 1},
.SHA1M = { 1490, 1},
.SHA1P = { 1491, 1},
.SHA256H = { 1492, 1},
.SHA256H2 = { 1493, 1},
.SHA256SU0 = { 1494, 1},
.SHA256SU1 = { 1495, 1},
.VJCVT = { 1496, 1},
.VSDOT = { 1497, 4},
.VUDOT = { 1501, 4},
.VDOT = { 1505, 2},
.VMMLA = { 1507, 1},
.VFMAL = { 1508, 2},
.VFMSL = { 1510, 2},
.VCMLA = { 1512, 5},
.VCADD = { 1517, 2},
.VSMMLA = { 1519, 1},
.VUMMLA = { 1520, 1},
.VUSMMLA = { 1521, 1},
.VSUDOT = { 1522, 2},
.VUSDOT = { 1524, 4},
.VQABS = { 1528, 1},
.VQNEG = { 1529, 1},
.VMOVX = { 1530, 1},
.VINS = { 1531, 1},
.VLD2R = { 1532, 1},
.VLD3R = { 1533, 1},
.VLD4R = { 1534, 1},
.IT = { 1535, 1},
.TT = { 1536, 1},
.TTT = { 1537, 1},
.TTA = { 1538, 1},
.TTAT = { 1539, 1},
.SG = { 1540, 1},
.BXNS = { 1541, 1},
.BLXNS = { 1542, 1},
.PAC = { 1543, 1},
.PACBTI = { 1544, 1},
.AUT = { 1545, 1},
.AUTG = { 1546, 1},
.BTI = { 1547, 1},
.WLS = { 1548, 1},
.WLSTP = { 1549, 1},
.DLS = { 1550, 1},
.DLSTP = { 1551, 1},
.LE = { 1552, 1},
.LETP = { 1553, 1},
.LCTP = { 1554, 1},
.BF = { 1555, 1},
.BFX = { 1556, 1},
.BFL = { 1557, 1},
.BFLX = { 1558, 1},
.BFCSEL = { 1559, 1},
.CX1 = { 1560, 1},
.CX1A = { 1561, 1},
.CX1D = { 1562, 1},
.CX1DA = { 1563, 1},
.CX2 = { 1564, 1},
.CX2A = { 1565, 1},
.CX2D = { 1566, 1},
.CX2DA = { 1567, 1},
.CX3 = { 1568, 1},
.CX3A = { 1569, 1},
.CX3D = { 1570, 1},
.CX3DA = { 1571, 1},
.VCX1 = { 1572, 2},
.VCX1A = { 1574, 2},
.VCX2 = { 1576, 2},
.VCX2A = { 1578, 2},
.VCX3 = { 1580, 2},
.VCX3A = { 1582, 2},
.VPT = { 1584, 1},
.VPST = { 1585, 1},
.VPSEL = { 1586, 1},
.VPNOT = { 1587, 1},
.VCTP = { 1588, 1},
.VADDV = { 1589, 1},
.VADDVA = { 1590, 1},
.VADDLV = { 1591, 1},
.VADDLVA = { 1592, 1},
.VMAXV = { 1593, 1},
.VMAXAV = { 1594, 1},
.VMINV = { 1595, 1},
.VMINAV = { 1596, 1},
.VMAXNMV = { 1597, 1},
.VMAXNMAV = { 1598, 1},
.VMINNMV = { 1599, 1},
.VMINNMAV = { 1600, 1},
.VABAV = { 1601, 1},
.VMLADAV = { 1602, 1},
.VMLADAVA = { 1603, 1},
.VMLADAVX = { 1604, 1},
.VMLADAVAX = { 1605, 1},
.VMLALDAV = { 1606, 1},
.VMLALDAVA = { 1607, 1},
.VMLALDAVX = { 1608, 1},
.VMLALDAVAX = { 1609, 1},
.VMLSDAV = { 1610, 1},
.VMLSDAVA = { 1611, 1},
.VMLSDAVX = { 1612, 1},
.VMLSDAVAX = { 1613, 1},
.VMLSLDAV = { 1614, 1},
.VMLSLDAVA = { 1615, 1},
.VMLSLDAVX = { 1616, 1},
.VMLSLDAVAX = { 1617, 1},
.VRMLALDAVH = { 1618, 1},
.VRMLALDAVHA = { 1619, 1},
.VRMLALDAVHX = { 1620, 1},
.VRMLALDAVHAX = { 1621, 1},
.VRMLSLDAVH = { 1622, 1},
.VRMLSLDAVHA = { 1623, 1},
.VRMLSLDAVHX = { 1624, 1},
.VRMLSLDAVHAX = { 1625, 1},
.VMLAV = { 1626, 1},
.VMLAVA = { 1627, 1},
.VMLSV = { 1628, 1},
.VMLSVA = { 1629, 1},
.VCMUL = { 1630, 1},
.VHCADD = { 1631, 2},
.VBRSR = { 1633, 1},
.VSHLC = { 1634, 1},
.VDDUP = { 1635, 1},
.VIDUP = { 1636, 1},
.VDWDUP = { 1637, 1},
.VIWDUP = { 1638, 1},
.VMOVNB = { 1639, 1},
.VMOVNT = { 1640, 1},
.VQMOVNB = { 1641, 1},
.VQMOVNT = { 1642, 1},
.VQMOVUNB = { 1643, 1},
.VQMOVUNT = { 1644, 1},
.VSHLLB = { 1645, 1},
.VSHLLT = { 1646, 1},
.VMULLB = { 1647, 1},
.VMULLT = { 1648, 1},
.VMLALB = { 1649, 1},
.VMLALT = { 1650, 1},
.VMLSLB = { 1651, 1},
.VMLSLT = { 1652, 1},
.VSHRNB = { 1653, 1},
.VSHRNT = { 1654, 1},
.VRSHRNB = { 1655, 1},
.VRSHRNT = { 1656, 1},
.VQSHRNB = { 1657, 1},
.VQSHRNT = { 1658, 1},
.VQRSHRNB = { 1659, 1},
.VQRSHRNT = { 1660, 1},
.VQSHRUNB = { 1661, 1},
.VQSHRUNT = { 1662, 1},
.VQRSHRUNB = { 1663, 1},
.VQRSHRUNT = { 1664, 1},
.VQDMLADH = { 1665, 1},
.VQDMLADHX = { 1666, 1},
.VQDMLSDH = { 1667, 1},
.VQDMLSDHX = { 1668, 1},
.VQRDMLADH = { 1669, 1},
.VQRDMLADHX = { 1670, 1},
.VQRDMLSDH = { 1671, 1},
.VQRDMLSDHX = { 1672, 1},
.VLDRB = { 1673, 2},
.VLDRH = { 1675, 2},
.VLDRW = { 1677, 2},
.VLDRD = { 1679, 2},
.VSTRB = { 1681, 2},
.VSTRH = { 1683, 2},
.VSTRW = { 1685, 2},
.VSTRD = { 1687, 2},
.VLD20 = { 1689, 1},
.VLD21 = { 1690, 1},
.VLD40 = { 1691, 1},
.VLD41 = { 1692, 1},
.VLD42 = { 1693, 1},
.VLD43 = { 1694, 1},
.VST20 = { 1695, 1},
.VST21 = { 1696, 1},
.VST40 = { 1697, 1},
.VST41 = { 1698, 1},
.VST42 = { 1699, 1},
.VST43 = { 1700, 1},
._COUNT = { 1701, 0},
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -132,8 +132,9 @@ run_smoke :: proc() {
check("VFMA.F32", .VFMA, 0, 0x0EA00A00, 0x0FB00B50)
check("VLDR.F32", .VLDR, 0, 0x0D100A00, 0x0F300F00)
check("VSTR.F64", .VSTR, 1, 0x0D000B00, 0x0F300F00)
check("VMRS", .VMRS, 0, 0x0EF10A10, 0x0FFF0FFF)
check("VMSR", .VMSR, 0, 0x0EE10A10, 0x0FFF0FFF)
// The system register is an operand now, so its field is not fixed.
check("VMRS", .VMRS, 0, 0x0EF10A10, 0x0FF00FFF)
check("VMSR", .VMSR, 0, 0x0EE10A10, 0x0FF00FFF)
check("VPUSH.F32", .VPUSH,0, 0x0D2D0A00, 0x0FFF0F00)
check("VPOP.F64", .VPOP, 1, 0x0CBD0B00, 0x0FFF0F00)
check("VCMP.F32", .VCMP, 0, 0x0EB40A40, 0x0FBF0FD0)
@@ -160,7 +161,9 @@ run_smoke :: proc() {
check("VMUL NEON.I8 D", .VMUL, 5, 0xF2000910, 0xFFB00F10)
check("VMUL NEON.F32 D", .VMUL, 13, 0xF3000D10, 0xFFB00F10)
check("VAND", .VAND, 0, 0xF2000110, 0xFFB00F10)
check("VORR", .VORR, 0, 0xF2200110, 0xFFB00F10)
// The modified-immediate forms come first; the register form follows.
check("VORR imm", .VORR, 0, 0xF2800110, 0xFEB80FF0)
check("VORR reg", .VORR, 12, 0xF2200110, 0xFFB00F10)
check("VEOR", .VEOR, 0, 0xF3000110, 0xFFB00F10)
check("VBSL", .VBSL, 0, 0xF3100110, 0xFFB00F10)
check("VMAX.S16 D", .VMAX, 1, 0xF2100600, 0xFFB00F10)