From fae03b995c69f9f0a5b4cc01e2efdf7451e6f0b9 Mon Sep 17 00:00:00 2001 From: Brendan Punsky Date: Sat, 29 Aug 2026 00:46:58 -0400 Subject: [PATCH] rexcode/arm32: operands that no field carries, and three forms with the wrong shape VSHLL's widest form shifts by exactly the element size. No field holds that amount -- the size is a fixed bit of the form, so the shift is too -- and the form printed no shift at all, which reads as a different instruction. VCADD and VCMLA name their rotation in degrees, 90 and 270 for one and all four quadrants for the other; both printed the raw field, so every rotation read as `#0`. VSEL is an unconditional word that still names a condition, in bits 21:20 and spelled on the mnemonic; it printed a bare `#0` operand instead and no condition. Only four conditions can be named and not in their usual order, so they get a small table. The shift amount had five bits, which cannot hold 32 -- the amount LSR and ASR reach through a zero field. It silently wrapped back to zero, which is why the previous commit's fix for those did not take. Memory had a spare bit and the register operand had two. Three forms were shaped wrong outright. VDUP from a GPR puts Vd in bits 19:16 with D at bit 7, not where NEON usually puts it, so it named a register sixteen too high. VCVTA, VCVTN, VCVTP and VCVTM to a 32-bit integer land in an S register whatever the source width, and the F64 forms had them landing in a D. VFMAL and VFMSL multiply pairs of half-precision values, so their sources are half the width of the destination -- S registers into a D, D registers into a Q -- and they carried no data type at all. VJCVT likewise: it converts F64 to a signed 32-bit integer. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_018UmHLRF11EoWwNWCJ7JGaA --- core/rexcode/isa/arm32/decoder.odin | 14 +++++- core/rexcode/isa/arm32/encoder.odin | 6 +++ core/rexcode/isa/arm32/encoding_types.odin | 10 +++- core/rexcode/isa/arm32/mnemonic_builders.odin | 30 ++++++------ core/rexcode/isa/arm32/operands.odin | 7 ++- .../isa/arm32/tablegen/encoding_table.odin | 44 +++++++++--------- .../tablegen/generated/decode_tables.odin | 44 +++++++++--------- .../tablegen/generated/encode_tables.odin | 44 +++++++++--------- .../isa/arm32/tables/arm32.encode_forms.bin | Bin 38249 -> 38249 bytes .../isa/arm32/tables/arm32.entries.bin | Bin 38249 -> 38249 bytes 10 files changed, 111 insertions(+), 88 deletions(-) diff --git a/core/rexcode/isa/arm32/decoder.odin b/core/rexcode/isa/arm32/decoder.odin index 4ef390294..3f3d710c8 100644 --- a/core/rexcode/isa/arm32/decoder.odin +++ b/core/rexcode/isa/arm32/decoder.odin @@ -157,7 +157,10 @@ find_and_decode :: proc(word: u32, mode: Mode, ilen: u32, inst: ^Instruction, in inst.dt = e.dt // Cond: A32 entries with bits[31:28] variable in mask take cond from word - if mode == .A32 && (e.mask >> 28) == 0 { + if e.flags.cond_in_21 { + // Four conditions only, and not in their usual order. + inst.cond = VSEL_CONDITIONS[(word >> 20) & 3] + } else if mode == .A32 && (e.mask >> 28) == 0 { inst.cond = u8((word >> 28) & 0xF) } else { inst.cond = 14 // AL / unconditional @@ -547,6 +550,11 @@ unpack_operand :: proc(word: u32, enc: Operand_Encoding, ot: Operand_Type) -> Op return op_imm(i64((word >> 18) & 0xF)) // ---- Saturate / bit field ---- + case .NEON_SHLL_8: return op_imm(8) + case .NEON_SHLL_16: return op_imm(16) + case .NEON_SHLL_32: return op_imm(32) + case .NEON_ROT_2: return op_imm(((word >> 24) & 1) != 0 ? 270 : 90) + case .NEON_ROT_4: return op_imm(i64(((word >> 20) & 3) * 90)) case .VFP_FBITS: // The fixed-point width is 16 or 32 by the sx bit, and the fraction // is that less imm4:i -- so the widest fraction encodes as zero. @@ -678,6 +686,10 @@ table_run_length :: #force_inline proc "contextless" (e: Operand_Encoding) -> u8 return 1 } +// The conditions VSEL can name, in the order bits 21:20 give them. +@(private="file") +VSEL_CONDITIONS := [4]u8{0, 6, 10, 12} // EQ, VS, GE, GT + // Typical-case estimate of the instruction count for `data`. @(require_results) decode_estimate_instruction_count :: #force_inline proc "contextless" (data: []u8) -> int { diff --git a/core/rexcode/isa/arm32/encoder.odin b/core/rexcode/isa/arm32/encoder.odin index 7d4805bb2..4fc95d9ee 100644 --- a/core/rexcode/isa/arm32/encoder.odin +++ b/core/rexcode/isa/arm32/encoder.odin @@ -661,6 +661,12 @@ pack_operand_inline :: #force_inline proc( case .IT_MASK: return u32(op.immediate) & 0xFF case .CPS_IFLAGS: return u32(op.immediate) & 0x1FF case .HINT_FIELD: return u32(op.immediate) & 0xFF + case .NEON_SHLL_8, .NEON_SHLL_16, .NEON_SHLL_32: + return 0 // the amount is the form's element size; no field carries it + case .NEON_ROT_2: + return (op.immediate == 270 ? u32(1) : 0) << 24 + case .NEON_ROT_4: + return ((u32(op.immediate) / 90) & 3) << 20 case .VFP_FBITS: // sx is a fixed bit of the form, so the width comes from its pattern. width: u32 = ((form.bits >> 7) & 1) != 0 ? 32 : 16 diff --git a/core/rexcode/isa/arm32/encoding_types.odin b/core/rexcode/isa/arm32/encoding_types.odin index 4d7333849..32ca83311 100644 --- a/core/rexcode/isa/arm32/encoding_types.odin +++ b/core/rexcode/isa/arm32/encoding_types.odin @@ -156,7 +156,9 @@ Encoding_Flags :: bit_field u8 { writes_pc: bool | 1, thumb32: bool | 1, // T32 32-bit form (vs 16-bit). Ignored for A32. deprecated: bool | 1, - _: u8 | 1, + // VSEL and friends are unconditional words that still name a condition, + // in bits 21:20 rather than 31:28, and spell it on the mnemonic. + cond_in_21: bool | 1, } // ---- Operand types ---------------------------------------------------------- @@ -412,6 +414,12 @@ Operand_Encoding :: enum u8 { // ---- Saturate ---- VFP_FBITS, // VCVT fixed-point fraction bits: width - (imm4:i) + // VSHLL's widest form shifts by exactly the element size, which no field + // carries -- the size is a fixed bit of the form, so the amount is too. + NEON_SHLL_8, NEON_SHLL_16, NEON_SHLL_32, + // Complex-arithmetic rotations, named in degrees. VCADD has two, in bit + // 24; VCMLA has four, in bits 21:20. + NEON_ROT_2, NEON_ROT_4, SAT_IMM5, // bits 20-16: SSAT/SSAT16 saturate-to width, less one SAT_IMM5_T32, // Thumb-2 signed saturate amount, less one SAT_IMM5_U, // bits 20-16: USAT/USAT16 width, which is not biased diff --git a/core/rexcode/isa/arm32/mnemonic_builders.odin b/core/rexcode/isa/arm32/mnemonic_builders.odin index 5e4bdd9a3..87763c9aa 100644 --- a/core/rexcode/isa/arm32/mnemonic_builders.odin +++ b/core/rexcode/isa/arm32/mnemonic_builders.odin @@ -758,8 +758,8 @@ inst_vpush_slist :: #force_inline proc "contextless" (regs: u16) -> In emit_vpush_slist :: #force_inline proc(instructions: ^[dynamic]Instruction, regs: u16) { append(instructions, inst_vpush_slist(regs)) } inst_vpop_slist :: #force_inline proc "contextless" (regs: u16) -> Instruction { return Instruction{mnemonic = .VPOP, operand_count = 1, mode = .A32, cond = 14, length = 4, ops = {op_reg_list(regs), {}, {}, {}}} } emit_vpop_slist :: #force_inline proc(instructions: ^[dynamic]Instruction, regs: u16) { append(instructions, inst_vpop_slist(regs)) } -inst_vsel_s_s_s_cond :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .VSEL, operand_count = 4, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), op_imm(imm)}} } -emit_vsel_s_s_s_cond :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register, imm: i64) { append(instructions, inst_vsel_s_s_s_cond(dst, src, src2, imm)) } +inst_vsel_s_s_s :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .VSEL, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), {}}} } +emit_vsel_s_s_s :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_vsel_s_s_s(dst, src, src2)) } inst_vmaxnm_s_s_s :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .VMAXNM, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), {}}} } emit_vmaxnm_s_s_s :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_vmaxnm_s_s_s(dst, src, src2)) } inst_vminnm_s_s_s :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .VMINNM, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), {}}} } @@ -959,9 +959,7 @@ emit_vshrn_d_q_imm :: #force_inline proc(instructions: ^[dynamic]Instruc inst_vrshrn_d_q_imm :: #force_inline proc "contextless" (dst: Register, src: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .VRSHRN, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_imm(imm), {}}} } emit_vrshrn_d_q_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, imm: i64) { append(instructions, inst_vrshrn_d_q_imm(dst, src, imm)) } inst_vshll_q_d_imm :: #force_inline proc "contextless" (dst: Register, src: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .VSHLL, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_imm(imm), {}}} } -inst_vshll_q_d :: #force_inline proc "contextless" (dst: Register, src: Register) -> Instruction { return Instruction{mnemonic = .VSHLL, operand_count = 2, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), {}, {}}} } emit_vshll_q_d_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, imm: i64) { append(instructions, inst_vshll_q_d_imm(dst, src, imm)) } -emit_vshll_q_d :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register) { append(instructions, inst_vshll_q_d(dst, src)) } inst_vcls_d_d :: #force_inline proc "contextless" (dst: Register, src: Register) -> Instruction { return Instruction{mnemonic = .VCLS, operand_count = 2, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), {}, {}}} } emit_vcls_d_d :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register) { append(instructions, inst_vcls_d_d(dst, src)) } inst_vclz_d_d :: #force_inline proc "contextless" (dst: Register, src: Register) -> Instruction { return Instruction{mnemonic = .VCLZ, operand_count = 2, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), {}, {}}} } @@ -1054,10 +1052,10 @@ inst_vdot_d_d_d :: #force_inline proc "contextless" (dst: Register, s emit_vdot_d_d_d :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_vdot_d_d_d(dst, src, src2)) } inst_vmmla_q_q_q :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .VMMLA, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), {}}} } emit_vmmla_q_q_q :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_vmmla_q_q_q(dst, src, src2)) } -inst_vfmal_d_d_d :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .VFMAL, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), {}}} } -emit_vfmal_d_d_d :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_vfmal_d_d_d(dst, src, src2)) } -inst_vfmsl_d_d_d :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .VFMSL, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), {}}} } -emit_vfmsl_d_d_d :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_vfmsl_d_d_d(dst, src, src2)) } +inst_vfmal_d_s_s :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .VFMAL, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), {}}} } +emit_vfmal_d_s_s :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_vfmal_d_s_s(dst, src, src2)) } +inst_vfmsl_d_s_s :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register) -> Instruction { return Instruction{mnemonic = .VFMSL, operand_count = 3, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), {}}} } +emit_vfmsl_d_s_s :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register) { append(instructions, inst_vfmsl_d_s_s(dst, src, src2)) } inst_vcmla_d_d_d_imm :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .VCMLA, operand_count = 4, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_reg(src2), op_imm(imm)}} } inst_vcmla_d_d_dlane_imm :: #force_inline proc "contextless" (dst: Register, src: Register, src2: Register, lane: u8, imm: i64) -> Instruction { return Instruction{mnemonic = .VCMLA, operand_count = 4, mode = .A32, cond = 14, length = 4, ops = {op_reg(dst), op_reg(src), op_dpr_lane(src2, lane), op_imm(imm)}} } emit_vcmla_d_d_d_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, src2: Register, imm: i64) { append(instructions, inst_vcmla_d_d_d_imm(dst, src, src2, imm)) } @@ -2001,8 +1999,8 @@ inst_vpush :: inst_vpush_slist emit_vpush :: emit_vpush_slist inst_vpop :: inst_vpop_slist emit_vpop :: emit_vpop_slist -inst_vsel :: inst_vsel_s_s_s_cond -emit_vsel :: emit_vsel_s_s_s_cond +inst_vsel :: inst_vsel_s_s_s +emit_vsel :: emit_vsel_s_s_s inst_vmaxnm :: inst_vmaxnm_s_s_s emit_vmaxnm :: emit_vmaxnm_s_s_s inst_vminnm :: inst_vminnm_s_s_s @@ -2167,8 +2165,8 @@ inst_vshrn :: inst_vshrn_d_q_imm emit_vshrn :: emit_vshrn_d_q_imm inst_vrshrn :: inst_vrshrn_d_q_imm emit_vrshrn :: emit_vrshrn_d_q_imm -inst_vshll :: proc{ inst_vshll_q_d_imm, inst_vshll_q_d } -emit_vshll :: proc{ emit_vshll_q_d_imm, emit_vshll_q_d } +inst_vshll :: inst_vshll_q_d_imm +emit_vshll :: emit_vshll_q_d_imm inst_vcls :: inst_vcls_d_d emit_vcls :: emit_vcls_d_d inst_vclz :: inst_vclz_d_d @@ -2251,10 +2249,10 @@ inst_vdot :: inst_vdot_d_d_d emit_vdot :: emit_vdot_d_d_d inst_vmmla :: inst_vmmla_q_q_q emit_vmmla :: emit_vmmla_q_q_q -inst_vfmal :: inst_vfmal_d_d_d -emit_vfmal :: emit_vfmal_d_d_d -inst_vfmsl :: inst_vfmsl_d_d_d -emit_vfmsl :: emit_vfmsl_d_d_d +inst_vfmal :: inst_vfmal_d_s_s +emit_vfmal :: emit_vfmal_d_s_s +inst_vfmsl :: inst_vfmsl_d_s_s +emit_vfmsl :: emit_vfmsl_d_s_s inst_vcmla :: proc{ inst_vcmla_d_d_d_imm, inst_vcmla_d_d_dlane_imm } emit_vcmla :: proc{ emit_vcmla_d_d_d_imm, emit_vcmla_d_d_dlane_imm } inst_vcadd :: inst_vcadd_d_d_d_imm diff --git a/core/rexcode/isa/arm32/operands.odin b/core/rexcode/isa/arm32/operands.odin index 4914fe0af..2ddab4af4 100644 --- a/core/rexcode/isa/arm32/operands.odin +++ b/core/rexcode/isa/arm32/operands.odin @@ -69,11 +69,10 @@ Memory :: bit_field u64 { base: Register | 15, // GPR base register index: Register | 15, // GPR, or Register(0) for imm-only forms shift_type: Shift_Type | 4, - shift_amt: u8 | 5, // 0..31 immediate shift + shift_amt: u8 | 6, // 0..32 -- LSR and ASR reach 32 through a zero field mode: Index_Mode | 2, sign: i8 | 3, // +1 or -1 (U bit) disp: i32 | 19, // immediate displacement (sign-extended) - // 1 bit spare } #assert(size_of(Memory) == 8) @@ -112,12 +111,12 @@ Operand :: struct #packed { using _: bit_field u32 { reg: Register | 15, shift_type: Shift_Type | 4, // GPR_SHIFTED; .LSL/0 when plain - shift_amt: u8 | 5, // 0..31, or the Rs index for RSR + 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, - // 2 bits spare + // 1 bit spare }, mem: Memory, immediate: i64, diff --git a/core/rexcode/isa/arm32/tablegen/encoding_table.odin b/core/rexcode/isa/arm32/tablegen/encoding_table.odin index 347e0116b..e1b7cb311 100644 --- a/core/rexcode/isa/arm32/tablegen/encoding_table.odin +++ b/core/rexcode/isa/arm32/tablegen/encoding_table.odin @@ -1588,19 +1588,19 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{ // ARMv8: VCVTA/N/P/M (rounding-mode FP-to-int) - cond=1111 (unconditional class) .VCVTA = { {.VCVTA, {.SPR, .SPR, .NONE, .NONE}, {.VD_S, .VM_S, .NONE, .NONE}, 0xFEBC0A40, 0xFFBF0FD0, .V8, .A32, {cond_in_28=false}, {.U32, .F32}}, - {.VCVTA, {.DPR, .DPR, .NONE, .NONE}, {.VD_D, .VM_D, .NONE, .NONE}, 0xFEBC0B40, 0xFFBF0FD0, .V8, .A32, {cond_in_28=false}, {.U32, .F64}}, + {.VCVTA, {.SPR, .DPR, .NONE, .NONE}, {.VD_S, .VM_D, .NONE, .NONE}, 0xFEBC0B40, 0xFFBF0FD0, .V8, .A32, {cond_in_28=false}, {.U32, .F64}}, }, .VCVTN = { {.VCVTN, {.SPR, .SPR, .NONE, .NONE}, {.VD_S, .VM_S, .NONE, .NONE}, 0xFEBD0A40, 0xFFBF0FD0, .V8, .A32, {cond_in_28=false}, {.U32, .F32}}, - {.VCVTN, {.DPR, .DPR, .NONE, .NONE}, {.VD_D, .VM_D, .NONE, .NONE}, 0xFEBD0B40, 0xFFBF0FD0, .V8, .A32, {cond_in_28=false}, {.U32, .F64}}, + {.VCVTN, {.SPR, .DPR, .NONE, .NONE}, {.VD_S, .VM_D, .NONE, .NONE}, 0xFEBD0B40, 0xFFBF0FD0, .V8, .A32, {cond_in_28=false}, {.U32, .F64}}, }, .VCVTP = { {.VCVTP, {.SPR, .SPR, .NONE, .NONE}, {.VD_S, .VM_S, .NONE, .NONE}, 0xFEBE0A40, 0xFFBF0FD0, .V8, .A32, {cond_in_28=false}, {.U32, .F32}}, - {.VCVTP, {.DPR, .DPR, .NONE, .NONE}, {.VD_D, .VM_D, .NONE, .NONE}, 0xFEBE0B40, 0xFFBF0FD0, .V8, .A32, {cond_in_28=false}, {.U32, .F64}}, + {.VCVTP, {.SPR, .DPR, .NONE, .NONE}, {.VD_S, .VM_D, .NONE, .NONE}, 0xFEBE0B40, 0xFFBF0FD0, .V8, .A32, {cond_in_28=false}, {.U32, .F64}}, }, .VCVTM = { {.VCVTM, {.SPR, .SPR, .NONE, .NONE}, {.VD_S, .VM_S, .NONE, .NONE}, 0xFEBF0A40, 0xFFBF0FD0, .V8, .A32, {cond_in_28=false}, {.U32, .F32}}, - {.VCVTM, {.DPR, .DPR, .NONE, .NONE}, {.VD_D, .VM_D, .NONE, .NONE}, 0xFEBF0B40, 0xFFBF0FD0, .V8, .A32, {cond_in_28=false}, {.U32, .F64}}, + {.VCVTM, {.SPR, .DPR, .NONE, .NONE}, {.VD_S, .VM_D, .NONE, .NONE}, 0xFEBF0B40, 0xFFBF0FD0, .V8, .A32, {cond_in_28=false}, {.U32, .F64}}, }, // VMRS / VMSR (access FPSCR + friends as GPR) @@ -1648,8 +1648,8 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{ }, .VSEL = { // VSEL.F32/F64 Sd, Sn, Sm -- cond field at bits 21-20 + 7 - {.VSEL, {.SPR, .SPR, .SPR, .COND}, {.VD_S, .VN_S, .VM_S, .NONE}, 0xFE000A00, 0xFF800F50, .V8, .A32, {cond_in_28=false}, {.F32, .NONE}}, - {.VSEL, {.DPR, .DPR, .DPR, .COND}, {.VD_D, .VN_D, .VM_D, .NONE}, 0xFE000B00, 0xFF800F50, .V8, .A32, {cond_in_28=false}, {.F64, .NONE}}, + {.VSEL, {.SPR, .SPR, .SPR, .NONE}, {.VD_S, .VN_S, .VM_S, .NONE}, 0xFE000A00, 0xFF800F50, .V8, .A32, {cond_in_28=false, cond_in_21=true}, {.F32, .NONE}}, + {.VSEL, {.DPR, .DPR, .DPR, .NONE}, {.VD_D, .VN_D, .VM_D, .NONE}, 0xFE000B00, 0xFF800F50, .V8, .A32, {cond_in_28=false, cond_in_21=true}, {.F64, .NONE}}, }, .VRINTA = { {.VRINTA, {.SPR, .SPR, .NONE, .NONE}, {.VD_S, .VM_S, .NONE, .NONE}, 0xFEB80A40, 0xFFBF0FD0, .V8, .A32, {cond_in_28=false}, {.F32, .NONE}}, @@ -1692,7 +1692,7 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{ {.VRINTX, {.QPR, .QPR, .NONE, .NONE}, {.VD_Q, .VM_Q, .NONE, .NONE}, 0xFFBA04C0, 0xFFBB0FD1, .MVE_FP, .T32, {thumb32=true, cond_in_28=false}, {.F32, .NONE}}, }, // VJCVT (ARMv8.3): F64 -> S32 with JS-style rounding - .VJCVT = { {.VJCVT, {.SPR, .DPR, .NONE, .NONE}, {.VD_S, .VM_D, .NONE, .NONE}, 0x0EB90BC0, 0x0FBF0FD0, .V8, .A32, {}, {}} }, + .VJCVT = { {.VJCVT, {.SPR, .DPR, .NONE, .NONE}, {.VD_S, .VM_D, .NONE, .NONE}, 0x0EB90BC0, 0x0FBF0FD0, .V8, .A32, {}, {.S32, .F64}} }, // ---- VFP F16 scalar arithmetic (FEAT_FP16) ---- // Uses coproc 9 (cp_num = 1001) instead of 10/11 used by F32/F64. @@ -2233,8 +2233,8 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{ // Variant: vector D[lane] form (1111 0011 1011 imm4 Vd 1100 0 Q M 0 Vm) // We list the common scalar/Rt form for V_8B/V_16B/V_4H/V_8H/V_2S/V_4S. // (encoder picks based on operand kinds) - {.VDUP, {.DPR, .GPR, .NONE, .NONE}, {.VD_D, .RT_A32, .NONE, .NONE}, 0x0EC00B10, 0x0FF00FD0, .NEON, .A32, {}, {.SZ8, .NONE}}, - {.VDUP, {.QPR, .GPR, .NONE, .NONE}, {.VD_Q, .RT_A32, .NONE, .NONE}, 0x0EE00B10, 0x0FF00FD0, .NEON, .A32, {}, {.SZ8, .NONE}}, + {.VDUP, {.DPR, .GPR, .NONE, .NONE}, {.VN_D, .RT_A32, .NONE, .NONE}, 0x0EC00B10, 0x0FF00FD0, .NEON, .A32, {}, {.SZ8, .NONE}}, + {.VDUP, {.QPR, .GPR, .NONE, .NONE}, {.VN_Q, .RT_A32, .NONE, .NONE}, 0x0EE00B10, 0x0FF00FD0, .NEON, .A32, {}, {.SZ8, .NONE}}, // VDUP from vector lane (.D form): 1111 0011 1011 imm4 Vd 1100 0 Q M 0 Vm {.VDUP, {.DPR, .DPR_ELEM, .NONE, .NONE}, {.VD_D, .NEON_VM_SCALAR_32, .NONE, .NONE}, 0xF3B00C00, 0xFFB00FD0, .NEON, .A32, {cond_in_28=false}, {}}, {.VDUP, {.QPR, .DPR_ELEM, .NONE, .NONE}, {.VD_Q, .NEON_VM_SCALAR_32, .NONE, .NONE}, 0xF3B00C40, 0xFFB00FD0, .NEON, .A32, {cond_in_28=false}, {}}, @@ -2548,9 +2548,9 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{ // imm6 encodes sh + size: 001sss for sh<8, 01sss for sh<16, 1sss for sh<32 {.VSHLL, {.QPR, .DPR, .IMM, .NONE}, {.VD_Q, .VM_D, .NEON_SHIFT_IMM6, .NONE}, 0xF2800A10, 0xFE800FD0, .NEON, .A32, {cond_in_28=false}, {.I16, .NONE}}, // VSHLL by max (#size) variant: 1111 0011 1 D 11 size 10 Vd 0011 0 0 M 0 Vm - {.VSHLL, {.QPR, .DPR, .NONE, .NONE}, {.VD_Q, .VM_D, .NONE, .NONE}, 0xF3B20300, 0xFFBF0FD0, .NEON, .A32, {cond_in_28=false}, {.I8, .NONE}}, - {.VSHLL, {.QPR, .DPR, .NONE, .NONE}, {.VD_Q, .VM_D, .NONE, .NONE}, 0xF3B60300, 0xFFBF0FD0, .NEON, .A32, {cond_in_28=false}, {.I16, .NONE}}, - {.VSHLL, {.QPR, .DPR, .NONE, .NONE}, {.VD_Q, .VM_D, .NONE, .NONE}, 0xF3BA0300, 0xFFBF0FD0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}}, + {.VSHLL, {.QPR, .DPR, .IMM, .NONE}, {.VD_Q, .VM_D, .NEON_SHLL_8, .NONE}, 0xF3B20300, 0xFFBF0FD0, .NEON, .A32, {cond_in_28=false}, {.I8, .NONE}}, + {.VSHLL, {.QPR, .DPR, .IMM, .NONE}, {.VD_Q, .VM_D, .NEON_SHLL_16, .NONE}, 0xF3B60300, 0xFFBF0FD0, .NEON, .A32, {cond_in_28=false}, {.I16, .NONE}}, + {.VSHLL, {.QPR, .DPR, .IMM, .NONE}, {.VD_Q, .VM_D, .NEON_SHLL_32, .NONE}, 0xF3BA0300, 0xFFBF0FD0, .NEON, .A32, {cond_in_28=false}, {.I32, .NONE}}, }, .VSHRN = { // 1111 0010 1 D imm6 Vd 1000 0 0 M 1 Vm @@ -2753,26 +2753,26 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{ // VCADD: rotation in bit 24 only (2 values: 90, 270 deg) .VCMLA = { // Mask 0xFC800F10 leaves bits 24:23 variable for rotation operand - {.VCMLA, {.DPR, .DPR, .DPR, .IMM}, {.VD_D, .VN_D, .VM_D, .NONE}, 0xFC200800, 0xFC800F10, .FCMA, .A32, {cond_in_28=false}, {.F16, .NONE}}, - {.VCMLA, {.QPR, .QPR, .QPR, .IMM}, {.VD_Q, .VN_Q, .VM_Q, .NONE}, 0xFC200840, 0xFC800F50, .FCMA, .A32, {cond_in_28=false}, {.F16, .NONE}}, - {.VCMLA, {.DPR, .DPR, .DPR_ELEM, .IMM}, {.VD_D, .VN_D, .NEON_VM_SCALAR_32, .NONE}, 0xFE000800, 0xFFB00F10, .FCMA, .A32, {cond_in_28=false}, {.F16, .NONE}}, - {.VCMLA, {.QPR, .QPR, .DPR_ELEM, .IMM}, {.VD_Q, .VN_Q, .NEON_VM_SCALAR_32, .NONE}, 0xFE000840, 0xFFB00F50, .FCMA, .A32, {cond_in_28=false}, {.F16, .NONE}}, + {.VCMLA, {.DPR, .DPR, .DPR, .IMM}, {.VD_D, .VN_D, .VM_D, .NEON_ROT_4}, 0xFC200800, 0xFC800F10, .FCMA, .A32, {cond_in_28=false}, {.F16, .NONE}}, + {.VCMLA, {.QPR, .QPR, .QPR, .IMM}, {.VD_Q, .VN_Q, .VM_Q, .NEON_ROT_4}, 0xFC200840, 0xFC800F50, .FCMA, .A32, {cond_in_28=false}, {.F16, .NONE}}, + {.VCMLA, {.DPR, .DPR, .DPR_ELEM, .IMM}, {.VD_D, .VN_D, .NEON_VM_SCALAR_32, .NEON_ROT_4}, 0xFE000800, 0xFFB00F10, .FCMA, .A32, {cond_in_28=false}, {.F16, .NONE}}, + {.VCMLA, {.QPR, .QPR, .DPR_ELEM, .IMM}, {.VD_Q, .VN_Q, .NEON_VM_SCALAR_32, .NEON_ROT_4}, 0xFE000840, 0xFFB00F50, .FCMA, .A32, {cond_in_28=false}, {.F16, .NONE}}, {.VCMLA, {.QPR, .QPR, .QPR, .IMM}, {.VD_Q, .VN_Q, .VM_Q, .MVE_ROT_CMLA}, 0xFC200840, 0xFE611FF1, .MVE_FP, .T32, {thumb32=true, cond_in_28=false}, {.F16, .NONE}}, }, .VCADD = { // Mask 0xFE800F10 leaves bit 24 variable for rotation operand (90 or 270) - {.VCADD, {.DPR, .DPR, .DPR, .IMM}, {.VD_D, .VN_D, .VM_D, .NONE}, 0xFC800800, 0xFE800F10, .FCMA, .A32, {cond_in_28=false}, {.F16, .NONE}}, - {.VCADD, {.QPR, .QPR, .QPR, .IMM}, {.VD_Q, .VN_Q, .VM_Q, .NONE}, 0xFC800840, 0xFE800F50, .FCMA, .A32, {cond_in_28=false}, {.F16, .NONE}}, + {.VCADD, {.DPR, .DPR, .DPR, .IMM}, {.VD_D, .VN_D, .VM_D, .NEON_ROT_2}, 0xFC800800, 0xFE800F10, .FCMA, .A32, {cond_in_28=false}, {.F16, .NONE}}, + {.VCADD, {.QPR, .QPR, .QPR, .IMM}, {.VD_Q, .VN_Q, .VM_Q, .NEON_ROT_2}, 0xFC800840, 0xFE800F50, .FCMA, .A32, {cond_in_28=false}, {.F16, .NONE}}, }, // FEAT_FHM (ARMv8.2): FP16 fused multiply-add long .VFMAL = { - {.VFMAL, {.DPR, .DPR, .DPR, .NONE}, {.VD_D, .VN_D, .VM_D, .NONE}, 0xFC200810, 0xFFB00F10, .FHM, .A32, {cond_in_28=false}, {}}, - {.VFMAL, {.QPR, .QPR, .QPR, .NONE}, {.VD_Q, .VN_Q, .VM_Q, .NONE}, 0xFC200850, 0xFFB00F50, .FHM, .A32, {cond_in_28=false}, {}}, + {.VFMAL, {.DPR, .SPR, .SPR, .NONE}, {.VD_D, .VN_S, .VM_S, .NONE}, 0xFC200810, 0xFFB00F10, .FHM, .A32, {cond_in_28=false}, {.F16, .NONE}}, + {.VFMAL, {.QPR, .DPR, .DPR, .NONE}, {.VD_Q, .VN_D, .VM_D, .NONE}, 0xFC200850, 0xFFB00F50, .FHM, .A32, {cond_in_28=false}, {.F16, .NONE}}, }, .VFMSL = { - {.VFMSL, {.DPR, .DPR, .DPR, .NONE}, {.VD_D, .VN_D, .VM_D, .NONE}, 0xFCA00810, 0xFFB00F10, .FHM, .A32, {cond_in_28=false}, {}}, - {.VFMSL, {.QPR, .QPR, .QPR, .NONE}, {.VD_Q, .VN_Q, .VM_Q, .NONE}, 0xFCA00850, 0xFFB00F50, .FHM, .A32, {cond_in_28=false}, {}}, + {.VFMSL, {.DPR, .SPR, .SPR, .NONE}, {.VD_D, .VN_S, .VM_S, .NONE}, 0xFCA00810, 0xFFB00F10, .FHM, .A32, {cond_in_28=false}, {.F16, .NONE}}, + {.VFMSL, {.QPR, .DPR, .DPR, .NONE}, {.VD_Q, .VN_D, .VM_D, .NONE}, 0xFCA00850, 0xFFB00F50, .FHM, .A32, {cond_in_28=false}, {.F16, .NONE}}, }, // FEAT_BF16 (ARMv8.6): BFloat16 arithmetic and conversion diff --git a/core/rexcode/isa/arm32/tablegen/generated/decode_tables.odin b/core/rexcode/isa/arm32/tablegen/generated/decode_tables.odin index 9d4c275f7..0e23ed2e7 100644 --- a/core/rexcode/isa/arm32/tablegen/generated/decode_tables.odin +++ b/core/rexcode/isa/arm32/tablegen/generated/decode_tables.odin @@ -723,9 +723,9 @@ DECODE_ENTRIES := [1663]lib.Decode_Entry{ { .VRSQRTE, {.QPR,.QPR,.NONE,.NONE}, {.VD_Q,.VM_Q,.NONE,.NONE}, 0xF3BB04C0, 0xFFBF0FD0, .NEON, .A32, {}, {.U32,.NONE} }, { .VRSQRTE, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0xF3BB0480, 0xFFBF0FD0, .NEON, .A32, {}, {.U32,.NONE} }, { .VRSQRTE, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0xF3BB0580, 0xFFBF0FD0, .NEON, .A32, {}, {.F32,.NONE} }, - { .VSHLL, {.QPR,.DPR,.NONE,.NONE}, {.VD_Q,.VM_D,.NONE,.NONE}, 0xF3BA0300, 0xFFBF0FD0, .NEON, .A32, {}, {.I32,.NONE} }, - { .VSHLL, {.QPR,.DPR,.NONE,.NONE}, {.VD_Q,.VM_D,.NONE,.NONE}, 0xF3B60300, 0xFFBF0FD0, .NEON, .A32, {}, {.I16,.NONE} }, - { .VSHLL, {.QPR,.DPR,.NONE,.NONE}, {.VD_Q,.VM_D,.NONE,.NONE}, 0xF3B20300, 0xFFBF0FD0, .NEON, .A32, {}, {.I8,.NONE} }, + { .VSHLL, {.QPR,.DPR,.IMM,.NONE}, {.VD_Q,.VM_D,.NEON_SHLL_32,.NONE}, 0xF3BA0300, 0xFFBF0FD0, .NEON, .A32, {}, {.I32,.NONE} }, + { .VSHLL, {.QPR,.DPR,.IMM,.NONE}, {.VD_Q,.VM_D,.NEON_SHLL_16,.NONE}, 0xF3B60300, 0xFFBF0FD0, .NEON, .A32, {}, {.I16,.NONE} }, + { .VSHLL, {.QPR,.DPR,.IMM,.NONE}, {.VD_Q,.VM_D,.NEON_SHLL_8,.NONE}, 0xF3B20300, 0xFFBF0FD0, .NEON, .A32, {}, {.I8,.NONE} }, { .VCLS, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0xF3B80400, 0xFFBF0FD0, .NEON, .A32, {}, {.S32,.NONE} }, { .VCLS, {.QPR,.QPR,.NONE,.NONE}, {.VD_Q,.VM_Q,.NONE,.NONE}, 0xF3B40440, 0xFFBF0FD0, .NEON, .A32, {}, {.S16,.NONE} }, { .VCLS, {.QPR,.QPR,.NONE,.NONE}, {.VD_Q,.VM_Q,.NONE,.NONE}, 0xF3B00440, 0xFFBF0FD0, .NEON, .A32, {}, {.S8,.NONE} }, @@ -1010,14 +1010,14 @@ DECODE_ENTRIES := [1663]lib.Decode_Entry{ { .LDC, {.COPROC_NUM,.COPROC_REG,.MEM,.NONE}, {.COPROC_NUM_FIELD,.COPROC_CRN_FIELD,.MEM_IMM8_OFFSET,.NONE}, 0x0C100000, 0x0F100000, .BASE, .A32, {}, {.NONE,.NONE} }, { .VSDOT, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFC200D40, 0xFFB00F50, .DOT, .A32, {}, {.S8,.NONE} }, { .VUDOT, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFC200D50, 0xFFB00F50, .DOT, .A32, {}, {.U8,.NONE} }, - { .VFMAL, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFC200850, 0xFFB00F50, .FHM, .A32, {}, {.NONE,.NONE} }, + { .VFMAL, {.QPR,.DPR,.DPR,.NONE}, {.VD_Q,.VN_D,.VM_D,.NONE}, 0xFC200850, 0xFFB00F50, .FHM, .A32, {}, {.F16,.NONE} }, { .VSMMLA, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFC200C40, 0xFFB00F50, .V8, .A32, {}, {.S8,.NONE} }, { .VUMMLA, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFC200C50, 0xFFB00F50, .V8, .A32, {}, {.U8,.NONE} }, { .VSDOT, {.DPR,.DPR,.DPR,.NONE}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFC200D00, 0xFFB00F10, .DOT, .A32, {}, {.S8,.NONE} }, { .VUDOT, {.DPR,.DPR,.DPR,.NONE}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFC200D10, 0xFFB00F10, .DOT, .A32, {}, {.U8,.NONE} }, - { .VFMAL, {.DPR,.DPR,.DPR,.NONE}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFC200810, 0xFFB00F10, .FHM, .A32, {}, {.NONE,.NONE} }, - { .VCMLA, {.QPR,.QPR,.QPR,.IMM}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFC200840, 0xFC800F50, .FCMA, .A32, {}, {.F16,.NONE} }, - { .VCMLA, {.DPR,.DPR,.DPR,.IMM}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFC200800, 0xFC800F10, .FCMA, .A32, {}, {.F16,.NONE} }, + { .VFMAL, {.DPR,.SPR,.SPR,.NONE}, {.VD_D,.VN_S,.VM_S,.NONE}, 0xFC200810, 0xFFB00F10, .FHM, .A32, {}, {.F16,.NONE} }, + { .VCMLA, {.QPR,.QPR,.QPR,.IMM}, {.VD_Q,.VN_Q,.VM_Q,.NEON_ROT_4}, 0xFC200840, 0xFC800F50, .FCMA, .A32, {}, {.F16,.NONE} }, + { .VCMLA, {.DPR,.DPR,.DPR,.IMM}, {.VD_D,.VN_D,.VM_D,.NEON_ROT_4}, 0xFC200800, 0xFC800F10, .FCMA, .A32, {}, {.F16,.NONE} }, { .VFMA, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFC300850, 0xFFB00F50, .BF16, .A32, {}, {.BF16,.NONE} }, { .VMOV, {.SPR,.SPR,.GPR,.GPR}, {.VM_S,.NONE,.RT_A32,.RT2_A32}, 0x0C400A10, 0x0FF00FD0, .VFPV2, .A32, {}, {.NONE,.NONE} }, { .VMOV, {.DPR,.GPR,.GPR,.NONE}, {.VM_D,.RT_A32,.RT2_A32,.NONE}, 0x0C400B10, 0x0FF00FD0, .VFPV2, .A32, {}, {.NONE,.NONE} }, @@ -1027,17 +1027,17 @@ DECODE_ENTRIES := [1663]lib.Decode_Entry{ { .VMOV, {.GPR,.GPR,.SPR,.SPR}, {.RT_A32,.RT2_A32,.VM_S,.NONE}, 0x0C500A10, 0x0FF00FD0, .VFPV2, .A32, {}, {.NONE,.NONE} }, { .MRRC2, {.COPROC_NUM,.IMM_COPROC_OP,.GPR,.GPR}, {.COPROC_NUM_FIELD,.COPROC_OPC_MCRR,.RT_A32,.RT2_A32}, 0xFC500000, 0xFFF00000, .V6, .A32, {}, {.NONE,.NONE} }, { .MRRC, {.COPROC_NUM,.IMM_COPROC_OP,.GPR,.GPR}, {.COPROC_NUM_FIELD,.COPROC_OPC_MCRR,.RT_A32,.RT2_A32}, 0x0C500000, 0x0FF00000, .V6, .A32, {}, {.NONE,.NONE} }, - { .VCADD, {.QPR,.QPR,.QPR,.IMM}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFC800840, 0xFE800F50, .FCMA, .A32, {}, {.F16,.NONE} }, - { .VCADD, {.DPR,.DPR,.DPR,.IMM}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFC800800, 0xFE800F10, .FCMA, .A32, {}, {.F16,.NONE} }, + { .VCADD, {.QPR,.QPR,.QPR,.IMM}, {.VD_Q,.VN_Q,.VM_Q,.NEON_ROT_2}, 0xFC800840, 0xFE800F50, .FCMA, .A32, {}, {.F16,.NONE} }, + { .VCADD, {.DPR,.DPR,.DPR,.IMM}, {.VD_D,.VN_D,.VM_D,.NEON_ROT_2}, 0xFC800800, 0xFE800F10, .FCMA, .A32, {}, {.F16,.NONE} }, { .VSTM, {.GPR,.DPR_LIST,.NONE,.NONE}, {.RN_A32,.VFP_D_LIST,.NONE,.NONE}, 0x0C800B00, 0x0F900F00, .VFPV2, .A32, {}, {.NONE,.NONE} }, { .VSTM, {.GPR,.SPR_LIST,.NONE,.NONE}, {.RN_A32,.VFP_S_LIST,.NONE,.NONE}, 0x0C800A00, 0x0F900F00, .VFPV2, .A32, {}, {.NONE,.NONE} }, { .VLDM, {.GPR,.DPR_LIST,.NONE,.NONE}, {.RN_A32,.VFP_D_LIST,.NONE,.NONE}, 0x0C900B00, 0x0F900F00, .VFPV2, .A32, {}, {.NONE,.NONE} }, { .VLDM, {.GPR,.SPR_LIST,.NONE,.NONE}, {.RN_A32,.VFP_S_LIST,.NONE,.NONE}, 0x0C900A00, 0x0F900F00, .VFPV2, .A32, {}, {.NONE,.NONE} }, - { .VFMSL, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFCA00850, 0xFFB00F50, .FHM, .A32, {}, {.NONE,.NONE} }, + { .VFMSL, {.QPR,.DPR,.DPR,.NONE}, {.VD_Q,.VN_D,.VM_D,.NONE}, 0xFCA00850, 0xFFB00F50, .FHM, .A32, {}, {.F16,.NONE} }, { .VUSMMLA, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFCA00C40, 0xFFB00F50, .V8, .A32, {}, {.S8,.NONE} }, { .VSUDOT, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFCA00D50, 0xFFB00F50, .V8, .A32, {}, {.NONE,.NONE} }, { .VUSDOT, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFCA00D40, 0xFFB00F50, .V8, .A32, {}, {.S8,.NONE} }, - { .VFMSL, {.DPR,.DPR,.DPR,.NONE}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFCA00810, 0xFFB00F10, .FHM, .A32, {}, {.NONE,.NONE} }, + { .VFMSL, {.DPR,.SPR,.SPR,.NONE}, {.VD_D,.VN_S,.VM_S,.NONE}, 0xFCA00810, 0xFFB00F10, .FHM, .A32, {}, {.F16,.NONE} }, { .VUSDOT, {.DPR,.DPR,.DPR,.NONE}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFCA00D00, 0xFFB00F10, .V8, .A32, {}, {.S8,.NONE} }, { .VPOP, {.SPR_LIST,.NONE,.NONE,.NONE}, {.VFP_S_LIST,.NONE,.NONE,.NONE}, 0x0CBD0A00, 0x0FFF0F00, .VFPV2, .A32, {}, {.NONE,.NONE} }, { .VPOP, {.DPR_LIST,.NONE,.NONE,.NONE}, {.VFP_D_LIST,.NONE,.NONE,.NONE}, 0x0CBD0B00, 0x0FFF0F00, .VFPV2, .A32, {}, {.NONE,.NONE} }, @@ -1050,10 +1050,10 @@ DECODE_ENTRIES := [1663]lib.Decode_Entry{ { .VMOV, {.SPR,.GPR,.NONE,.NONE}, {.VN_S,.RT_A32,.NONE,.NONE}, 0x0E000A10, 0x0FF00F7F, .VFPV2, .A32, {}, {.NONE,.NONE} }, { .VMOV, {.DPR_ELEM,.GPR,.NONE,.NONE}, {.VMOV_LANE_32,.RT_A32,.NONE,.NONE}, 0x0E000B10, 0x0FD00F7F, .VFPV2, .A32, {}, {.SZ32,.NONE} }, { .VMOV, {.DPR_ELEM,.GPR,.NONE,.NONE}, {.VMOV_LANE_16,.RT_A32,.NONE,.NONE}, 0x0E000B30, 0x0FD00F3F, .VFPV2, .A32, {}, {.SZ16,.NONE} }, - { .VCMLA, {.QPR,.QPR,.DPR_ELEM,.IMM}, {.VD_Q,.VN_Q,.NEON_VM_SCALAR_32,.NONE}, 0xFE000840, 0xFFB00F50, .FCMA, .A32, {}, {.F16,.NONE} }, - { .VCMLA, {.DPR,.DPR,.DPR_ELEM,.IMM}, {.VD_D,.VN_D,.NEON_VM_SCALAR_32,.NONE}, 0xFE000800, 0xFFB00F10, .FCMA, .A32, {}, {.F16,.NONE} }, - { .VSEL, {.DPR,.DPR,.DPR,.COND}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFE000B00, 0xFF800F50, .V8, .A32, {}, {.F64,.NONE} }, - { .VSEL, {.SPR,.SPR,.SPR,.COND}, {.VD_S,.VN_S,.VM_S,.NONE}, 0xFE000A00, 0xFF800F50, .V8, .A32, {}, {.F32,.NONE} }, + { .VCMLA, {.QPR,.QPR,.DPR_ELEM,.IMM}, {.VD_Q,.VN_Q,.NEON_VM_SCALAR_32,.NEON_ROT_4}, 0xFE000840, 0xFFB00F50, .FCMA, .A32, {}, {.F16,.NONE} }, + { .VCMLA, {.DPR,.DPR,.DPR_ELEM,.IMM}, {.VD_D,.VN_D,.NEON_VM_SCALAR_32,.NEON_ROT_4}, 0xFE000800, 0xFFB00F10, .FCMA, .A32, {}, {.F16,.NONE} }, + { .VSEL, {.DPR,.DPR,.DPR,.NONE}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFE000B00, 0xFF800F50, .V8, .A32, {}, {.F64,.NONE} }, + { .VSEL, {.SPR,.SPR,.SPR,.NONE}, {.VD_S,.VN_S,.VM_S,.NONE}, 0xFE000A00, 0xFF800F50, .V8, .A32, {}, {.F32,.NONE} }, { .VMLA, {.SPR,.SPR,.SPR,.NONE}, {.VD_S,.VN_S,.VM_S,.NONE}, 0x0E000900, 0x0FB00F50, .HALF_FP, .A32, {}, {.F16,.NONE} }, { .VMLS, {.SPR,.SPR,.SPR,.NONE}, {.VD_S,.VN_S,.VM_S,.NONE}, 0x0E000940, 0x0FB00F50, .HALF_FP, .A32, {}, {.F16,.NONE} }, { .VMLA, {.SPR,.SPR,.SPR,.NONE}, {.VD_S,.VN_S,.VM_S,.NONE}, 0x0E000A00, 0x0FB00B50, .VFPV2, .A32, {}, {.F32,.NONE} }, @@ -1115,13 +1115,13 @@ DECODE_ENTRIES := [1663]lib.Decode_Entry{ { .VCMP, {.DPR,.IMM,.NONE,.NONE}, {.VD_D,.IMPL,.NONE,.NONE}, 0x0EB50B40, 0x0FBF0FFF, .VFPV2, .A32, {}, {.F64,.NONE} }, { .VCMPE, {.DPR,.IMM,.NONE,.NONE}, {.VD_D,.IMPL,.NONE,.NONE}, 0x0EB50BC0, 0x0FBF0FFF, .VFPV2, .A32, {}, {.F64,.NONE} }, { .VCMPE, {.SPR,.IMM,.NONE,.NONE}, {.VD_S,.IMPL,.NONE,.NONE}, 0x0EB50AC0, 0x0FBF0FFF, .VFPV2, .A32, {}, {.F32,.NONE} }, - { .VCVTA, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0xFEBC0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, + { .VCVTA, {.SPR,.DPR,.NONE,.NONE}, {.VD_S,.VM_D,.NONE,.NONE}, 0xFEBC0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, { .VCVTA, {.SPR,.SPR,.NONE,.NONE}, {.VD_S,.VM_S,.NONE,.NONE}, 0xFEBC0A40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F32} }, { .VCVTN, {.SPR,.SPR,.NONE,.NONE}, {.VD_S,.VM_S,.NONE,.NONE}, 0xFEBD0A40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F32} }, - { .VCVTN, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0xFEBD0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, + { .VCVTN, {.SPR,.DPR,.NONE,.NONE}, {.VD_S,.VM_D,.NONE,.NONE}, 0xFEBD0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, { .VCVTP, {.SPR,.SPR,.NONE,.NONE}, {.VD_S,.VM_S,.NONE,.NONE}, 0xFEBE0A40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F32} }, - { .VCVTP, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0xFEBE0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, - { .VCVTM, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0xFEBF0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, + { .VCVTP, {.SPR,.DPR,.NONE,.NONE}, {.VD_S,.VM_D,.NONE,.NONE}, 0xFEBE0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, + { .VCVTM, {.SPR,.DPR,.NONE,.NONE}, {.VD_S,.VM_D,.NONE,.NONE}, 0xFEBF0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, { .VCVTM, {.SPR,.SPR,.NONE,.NONE}, {.VD_S,.VM_S,.NONE,.NONE}, 0xFEBF0A40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F32} }, { .VRINTA, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0xFEB80B40, 0xFFBF0FD0, .V8, .A32, {}, {.F64,.NONE} }, { .VRINTA, {.SPR,.SPR,.NONE,.NONE}, {.VD_S,.VM_S,.NONE,.NONE}, 0xFEB80A40, 0xFFBF0FD0, .V8, .A32, {}, {.F32,.NONE} }, @@ -1193,12 +1193,12 @@ DECODE_ENTRIES := [1663]lib.Decode_Entry{ { .VRINTZ, {.SPR,.SPR,.NONE,.NONE}, {.VD_S,.VM_S,.NONE,.NONE}, 0x0EB60AC0, 0x0FBF0FD0, .V8, .A32, {}, {.F32,.NONE} }, { .VRINTX, {.SPR,.SPR,.NONE,.NONE}, {.VD_S,.VM_S,.NONE,.NONE}, 0x0EB70A40, 0x0FBF0FD0, .V8, .A32, {}, {.F32,.NONE} }, { .VRINTX, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0x0EB70B40, 0x0FBF0FD0, .V8, .A32, {}, {.F64,.NONE} }, - { .VJCVT, {.SPR,.DPR,.NONE,.NONE}, {.VD_S,.VM_D,.NONE,.NONE}, 0x0EB90BC0, 0x0FBF0FD0, .V8, .A32, {}, {.NONE,.NONE} }, + { .VJCVT, {.SPR,.DPR,.NONE,.NONE}, {.VD_S,.VM_D,.NONE,.NONE}, 0x0EB90BC0, 0x0FBF0FD0, .V8, .A32, {}, {.S32,.F64} }, { .VMOV, {.DPR,.IMM8,.NONE,.NONE}, {.VD_D,.VFP_IMM8,.NONE,.NONE}, 0x0EB00B00, 0x0FB00FF0, .VFPV3, .A32, {}, {.F64,.NONE} }, { .VMOV, {.SPR,.IMM8,.NONE,.NONE}, {.VD_S,.VFP_IMM8,.NONE,.NONE}, 0x0EB00A00, 0x0FB00FF0, .VFPV3, .A32, {}, {.F32,.NONE} }, - { .VDUP, {.DPR,.GPR,.NONE,.NONE}, {.VD_D,.RT_A32,.NONE,.NONE}, 0x0EC00B10, 0x0FF00FD0, .NEON, .A32, {}, {.SZ8,.NONE} }, + { .VDUP, {.DPR,.GPR,.NONE,.NONE}, {.VN_D,.RT_A32,.NONE,.NONE}, 0x0EC00B10, 0x0FF00FD0, .NEON, .A32, {}, {.SZ8,.NONE} }, { .VMSR, {.GPR,.NONE,.NONE,.NONE}, {.RT_A32,.NONE,.NONE,.NONE}, 0x0EE10A10, 0x0FFF0FFF, .VFPV2, .A32, {}, {.NONE,.NONE} }, - { .VDUP, {.QPR,.GPR,.NONE,.NONE}, {.VD_Q,.RT_A32,.NONE,.NONE}, 0x0EE00B10, 0x0FF00FD0, .NEON, .A32, {}, {.SZ8,.NONE} }, + { .VDUP, {.QPR,.GPR,.NONE,.NONE}, {.VN_Q,.RT_A32,.NONE,.NONE}, 0x0EE00B10, 0x0FF00FD0, .NEON, .A32, {}, {.SZ8,.NONE} }, { .VMRS, {.GPR,.NONE,.NONE,.NONE}, {.RT_A32,.NONE,.NONE,.NONE}, 0x0EF10A10, 0x0FFF0FFF, .VFPV2, .A32, {}, {.NONE,.NONE} }, { .SVC, {.IMM,.NONE,.NONE,.NONE}, {.A32_IMM24,.NONE,.NONE,.NONE}, 0x0F000000, 0x0F000000, .BASE, .A32, {}, {.NONE,.NONE} }, { .SG, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0xE97FE97F, 0xFFFFFFFF, .V8M_SE, .T32, {thumb32=true}, {.NONE,.NONE} }, diff --git a/core/rexcode/isa/arm32/tablegen/generated/encode_tables.odin b/core/rexcode/isa/arm32/tablegen/generated/encode_tables.odin index f8d26009b..00802981e 100644 --- a/core/rexcode/isa/arm32/tablegen/generated/encode_tables.odin +++ b/core/rexcode/isa/arm32/tablegen/generated/encode_tables.odin @@ -1097,16 +1097,16 @@ ENCODE_FORMS := [1663]lib.Encoding{ { .VCVTT, {.SPR,.SPR,.NONE,.NONE}, {.VD_S,.VM_S,.NONE,.NONE}, 0x0EB30AC0, 0x0FBF0FD0, .VFPV3, .A32, {}, {.F16,.F32} }, // .VCVTA { .VCVTA, {.SPR,.SPR,.NONE,.NONE}, {.VD_S,.VM_S,.NONE,.NONE}, 0xFEBC0A40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F32} }, - { .VCVTA, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0xFEBC0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, + { .VCVTA, {.SPR,.DPR,.NONE,.NONE}, {.VD_S,.VM_D,.NONE,.NONE}, 0xFEBC0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, // .VCVTN { .VCVTN, {.SPR,.SPR,.NONE,.NONE}, {.VD_S,.VM_S,.NONE,.NONE}, 0xFEBD0A40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F32} }, - { .VCVTN, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0xFEBD0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, + { .VCVTN, {.SPR,.DPR,.NONE,.NONE}, {.VD_S,.VM_D,.NONE,.NONE}, 0xFEBD0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, // .VCVTP { .VCVTP, {.SPR,.SPR,.NONE,.NONE}, {.VD_S,.VM_S,.NONE,.NONE}, 0xFEBE0A40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F32} }, - { .VCVTP, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0xFEBE0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, + { .VCVTP, {.SPR,.DPR,.NONE,.NONE}, {.VD_S,.VM_D,.NONE,.NONE}, 0xFEBE0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, // .VCVTM { .VCVTM, {.SPR,.SPR,.NONE,.NONE}, {.VD_S,.VM_S,.NONE,.NONE}, 0xFEBF0A40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F32} }, - { .VCVTM, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0xFEBF0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, + { .VCVTM, {.SPR,.DPR,.NONE,.NONE}, {.VD_S,.VM_D,.NONE,.NONE}, 0xFEBF0B40, 0xFFBF0FD0, .V8, .A32, {}, {.U32,.F64} }, // .VCVTR { .VCVTR, {.SPR,.SPR,.NONE,.NONE}, {.VD_S,.VM_S,.NONE,.NONE}, 0x0EBD0A40, 0x0FBF0FD0, .VFPV2, .A32, {}, {.S32,.F32} }, { .VCVTR, {.SPR,.SPR,.NONE,.NONE}, {.VD_S,.VM_S,.NONE,.NONE}, 0x0EBC0A40, 0x0FBF0FD0, .VFPV2, .A32, {}, {.U32,.F32} }, @@ -1169,8 +1169,8 @@ ENCODE_FORMS := [1663]lib.Encoding{ { .VPOP, {.SPR_LIST,.NONE,.NONE,.NONE}, {.VFP_S_LIST,.NONE,.NONE,.NONE}, 0x0CBD0A00, 0x0FFF0F00, .VFPV2, .A32, {}, {.NONE,.NONE} }, { .VPOP, {.DPR_LIST,.NONE,.NONE,.NONE}, {.VFP_D_LIST,.NONE,.NONE,.NONE}, 0x0CBD0B00, 0x0FFF0F00, .VFPV2, .A32, {}, {.NONE,.NONE} }, // .VSEL - { .VSEL, {.SPR,.SPR,.SPR,.COND}, {.VD_S,.VN_S,.VM_S,.NONE}, 0xFE000A00, 0xFF800F50, .V8, .A32, {}, {.F32,.NONE} }, - { .VSEL, {.DPR,.DPR,.DPR,.COND}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFE000B00, 0xFF800F50, .V8, .A32, {}, {.F64,.NONE} }, + { .VSEL, {.SPR,.SPR,.SPR,.NONE}, {.VD_S,.VN_S,.VM_S,.NONE}, 0xFE000A00, 0xFF800F50, .V8, .A32, {}, {.F32,.NONE} }, + { .VSEL, {.DPR,.DPR,.DPR,.NONE}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFE000B00, 0xFF800F50, .V8, .A32, {}, {.F64,.NONE} }, // .VMAXNM { .VMAXNM, {.SPR,.SPR,.SPR,.NONE}, {.VD_S,.VN_S,.VM_S,.NONE}, 0xFE800A00, 0xFFB00B50, .V8, .A32, {}, {.F32,.NONE} }, { .VMAXNM, {.DPR,.DPR,.DPR,.NONE}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFE800B00, 0xFFB00B50, .V8, .A32, {}, {.F64,.NONE} }, @@ -1720,9 +1720,9 @@ ENCODE_FORMS := [1663]lib.Encoding{ { .VRSHRN, {.DPR,.QPR,.IMM,.NONE}, {.VD_D,.VM_Q,.NEON_SHIFT_IMM6,.NONE}, 0xF2800850, 0xFE800FD0, .NEON, .A32, {}, {.I16,.NONE} }, // .VSHLL { .VSHLL, {.QPR,.DPR,.IMM,.NONE}, {.VD_Q,.VM_D,.NEON_SHIFT_IMM6,.NONE}, 0xF2800A10, 0xFE800FD0, .NEON, .A32, {}, {.I16,.NONE} }, - { .VSHLL, {.QPR,.DPR,.NONE,.NONE}, {.VD_Q,.VM_D,.NONE,.NONE}, 0xF3B20300, 0xFFBF0FD0, .NEON, .A32, {}, {.I8,.NONE} }, - { .VSHLL, {.QPR,.DPR,.NONE,.NONE}, {.VD_Q,.VM_D,.NONE,.NONE}, 0xF3B60300, 0xFFBF0FD0, .NEON, .A32, {}, {.I16,.NONE} }, - { .VSHLL, {.QPR,.DPR,.NONE,.NONE}, {.VD_Q,.VM_D,.NONE,.NONE}, 0xF3BA0300, 0xFFBF0FD0, .NEON, .A32, {}, {.I32,.NONE} }, + { .VSHLL, {.QPR,.DPR,.IMM,.NONE}, {.VD_Q,.VM_D,.NEON_SHLL_8,.NONE}, 0xF3B20300, 0xFFBF0FD0, .NEON, .A32, {}, {.I8,.NONE} }, + { .VSHLL, {.QPR,.DPR,.IMM,.NONE}, {.VD_Q,.VM_D,.NEON_SHLL_16,.NONE}, 0xF3B60300, 0xFFBF0FD0, .NEON, .A32, {}, {.I16,.NONE} }, + { .VSHLL, {.QPR,.DPR,.IMM,.NONE}, {.VD_Q,.VM_D,.NEON_SHLL_32,.NONE}, 0xF3BA0300, 0xFFBF0FD0, .NEON, .A32, {}, {.I32,.NONE} }, // .VCLS { .VCLS, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0xF3B00400, 0xFFBF0FD0, .NEON, .A32, {}, {.S8,.NONE} }, { .VCLS, {.DPR,.DPR,.NONE,.NONE}, {.VD_D,.VM_D,.NONE,.NONE}, 0xF3B40400, 0xFFBF0FD0, .NEON, .A32, {}, {.S16,.NONE} }, @@ -1788,8 +1788,8 @@ ENCODE_FORMS := [1663]lib.Encoding{ { .VZIP, {.QPR,.QPR,.NONE,.NONE}, {.VD_Q,.VM_Q,.NONE,.NONE}, 0xF3B601C0, 0xFFBF0FD0, .NEON, .A32, {}, {.SZ16,.NONE} }, { .VZIP, {.QPR,.QPR,.NONE,.NONE}, {.VD_Q,.VM_Q,.NONE,.NONE}, 0xF3BA01C0, 0xFFBF0FD0, .NEON, .A32, {}, {.SZ32,.NONE} }, // .VDUP - { .VDUP, {.DPR,.GPR,.NONE,.NONE}, {.VD_D,.RT_A32,.NONE,.NONE}, 0x0EC00B10, 0x0FF00FD0, .NEON, .A32, {}, {.SZ8,.NONE} }, - { .VDUP, {.QPR,.GPR,.NONE,.NONE}, {.VD_Q,.RT_A32,.NONE,.NONE}, 0x0EE00B10, 0x0FF00FD0, .NEON, .A32, {}, {.SZ8,.NONE} }, + { .VDUP, {.DPR,.GPR,.NONE,.NONE}, {.VN_D,.RT_A32,.NONE,.NONE}, 0x0EC00B10, 0x0FF00FD0, .NEON, .A32, {}, {.SZ8,.NONE} }, + { .VDUP, {.QPR,.GPR,.NONE,.NONE}, {.VN_Q,.RT_A32,.NONE,.NONE}, 0x0EE00B10, 0x0FF00FD0, .NEON, .A32, {}, {.SZ8,.NONE} }, { .VDUP, {.DPR,.DPR_ELEM,.NONE,.NONE}, {.VD_D,.NEON_VM_SCALAR_32,.NONE,.NONE}, 0xF3B00C00, 0xFFB00FD0, .NEON, .A32, {}, {.NONE,.NONE} }, { .VDUP, {.QPR,.DPR_ELEM,.NONE,.NONE}, {.VD_Q,.NEON_VM_SCALAR_32,.NONE,.NONE}, 0xF3B00C40, 0xFFB00FD0, .NEON, .A32, {}, {.NONE,.NONE} }, { .VDUP, {.QPR,.GPR,.NONE,.NONE}, {.VD_Q,.RT_T32,.NONE,.NONE}, 0xEE800B10, 0xFF900F5F, .MVE_INT, .T32, {thumb32=true}, {.SZ32,.NONE} }, @@ -1880,7 +1880,7 @@ ENCODE_FORMS := [1663]lib.Encoding{ // .SHA256SU1 { .SHA256SU1, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xF3200C40, 0xFFB00F50, .CRYPTO, .A32, {}, {.SZ32,.NONE} }, // .VJCVT - { .VJCVT, {.SPR,.DPR,.NONE,.NONE}, {.VD_S,.VM_D,.NONE,.NONE}, 0x0EB90BC0, 0x0FBF0FD0, .V8, .A32, {}, {.NONE,.NONE} }, + { .VJCVT, {.SPR,.DPR,.NONE,.NONE}, {.VD_S,.VM_D,.NONE,.NONE}, 0x0EB90BC0, 0x0FBF0FD0, .V8, .A32, {}, {.S32,.F64} }, // .VSDOT { .VSDOT, {.DPR,.DPR,.DPR,.NONE}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFC200D00, 0xFFB00F10, .DOT, .A32, {}, {.S8,.NONE} }, { .VSDOT, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFC200D40, 0xFFB00F50, .DOT, .A32, {}, {.S8,.NONE} }, @@ -1897,20 +1897,20 @@ ENCODE_FORMS := [1663]lib.Encoding{ // .VMMLA { .VMMLA, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFC000C40, 0xFFB00F50, .BF16, .A32, {}, {.BF16,.NONE} }, // .VFMAL - { .VFMAL, {.DPR,.DPR,.DPR,.NONE}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFC200810, 0xFFB00F10, .FHM, .A32, {}, {.NONE,.NONE} }, - { .VFMAL, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFC200850, 0xFFB00F50, .FHM, .A32, {}, {.NONE,.NONE} }, + { .VFMAL, {.DPR,.SPR,.SPR,.NONE}, {.VD_D,.VN_S,.VM_S,.NONE}, 0xFC200810, 0xFFB00F10, .FHM, .A32, {}, {.F16,.NONE} }, + { .VFMAL, {.QPR,.DPR,.DPR,.NONE}, {.VD_Q,.VN_D,.VM_D,.NONE}, 0xFC200850, 0xFFB00F50, .FHM, .A32, {}, {.F16,.NONE} }, // .VFMSL - { .VFMSL, {.DPR,.DPR,.DPR,.NONE}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFCA00810, 0xFFB00F10, .FHM, .A32, {}, {.NONE,.NONE} }, - { .VFMSL, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFCA00850, 0xFFB00F50, .FHM, .A32, {}, {.NONE,.NONE} }, + { .VFMSL, {.DPR,.SPR,.SPR,.NONE}, {.VD_D,.VN_S,.VM_S,.NONE}, 0xFCA00810, 0xFFB00F10, .FHM, .A32, {}, {.F16,.NONE} }, + { .VFMSL, {.QPR,.DPR,.DPR,.NONE}, {.VD_Q,.VN_D,.VM_D,.NONE}, 0xFCA00850, 0xFFB00F50, .FHM, .A32, {}, {.F16,.NONE} }, // .VCMLA - { .VCMLA, {.DPR,.DPR,.DPR,.IMM}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFC200800, 0xFC800F10, .FCMA, .A32, {}, {.F16,.NONE} }, - { .VCMLA, {.QPR,.QPR,.QPR,.IMM}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFC200840, 0xFC800F50, .FCMA, .A32, {}, {.F16,.NONE} }, - { .VCMLA, {.DPR,.DPR,.DPR_ELEM,.IMM}, {.VD_D,.VN_D,.NEON_VM_SCALAR_32,.NONE}, 0xFE000800, 0xFFB00F10, .FCMA, .A32, {}, {.F16,.NONE} }, - { .VCMLA, {.QPR,.QPR,.DPR_ELEM,.IMM}, {.VD_Q,.VN_Q,.NEON_VM_SCALAR_32,.NONE}, 0xFE000840, 0xFFB00F50, .FCMA, .A32, {}, {.F16,.NONE} }, + { .VCMLA, {.DPR,.DPR,.DPR,.IMM}, {.VD_D,.VN_D,.VM_D,.NEON_ROT_4}, 0xFC200800, 0xFC800F10, .FCMA, .A32, {}, {.F16,.NONE} }, + { .VCMLA, {.QPR,.QPR,.QPR,.IMM}, {.VD_Q,.VN_Q,.VM_Q,.NEON_ROT_4}, 0xFC200840, 0xFC800F50, .FCMA, .A32, {}, {.F16,.NONE} }, + { .VCMLA, {.DPR,.DPR,.DPR_ELEM,.IMM}, {.VD_D,.VN_D,.NEON_VM_SCALAR_32,.NEON_ROT_4}, 0xFE000800, 0xFFB00F10, .FCMA, .A32, {}, {.F16,.NONE} }, + { .VCMLA, {.QPR,.QPR,.DPR_ELEM,.IMM}, {.VD_Q,.VN_Q,.NEON_VM_SCALAR_32,.NEON_ROT_4}, 0xFE000840, 0xFFB00F50, .FCMA, .A32, {}, {.F16,.NONE} }, { .VCMLA, {.QPR,.QPR,.QPR,.IMM}, {.VD_Q,.VN_Q,.VM_Q,.MVE_ROT_CMLA}, 0xFC200840, 0xFE611FF1, .MVE_FP, .T32, {thumb32=true}, {.F16,.NONE} }, // .VCADD - { .VCADD, {.DPR,.DPR,.DPR,.IMM}, {.VD_D,.VN_D,.VM_D,.NONE}, 0xFC800800, 0xFE800F10, .FCMA, .A32, {}, {.F16,.NONE} }, - { .VCADD, {.QPR,.QPR,.QPR,.IMM}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFC800840, 0xFE800F50, .FCMA, .A32, {}, {.F16,.NONE} }, + { .VCADD, {.DPR,.DPR,.DPR,.IMM}, {.VD_D,.VN_D,.VM_D,.NEON_ROT_2}, 0xFC800800, 0xFE800F10, .FCMA, .A32, {}, {.F16,.NONE} }, + { .VCADD, {.QPR,.QPR,.QPR,.IMM}, {.VD_Q,.VN_Q,.VM_Q,.NEON_ROT_2}, 0xFC800840, 0xFE800F50, .FCMA, .A32, {}, {.F16,.NONE} }, // .VSMMLA { .VSMMLA, {.QPR,.QPR,.QPR,.NONE}, {.VD_Q,.VN_Q,.VM_Q,.NONE}, 0xFC200C40, 0xFFB00F50, .V8, .A32, {}, {.S8,.NONE} }, // .VUMMLA diff --git a/core/rexcode/isa/arm32/tables/arm32.encode_forms.bin b/core/rexcode/isa/arm32/tables/arm32.encode_forms.bin index 3960c23748a4c5fbd4cb7ccdcf30328a53a57293..54ae728c545484b4004272318946daa04ae84cce 100644 GIT binary patch delta 1966 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 delta 1863 zcmaF4is|JlrVXvi^$iRHoDH8Y@HhMuU|`^4C}HH}5@68KZD0sM7A}Je3veK*E{6*T zAPZM8a&ZbUXlpev2yh{(&Sd1`5@65^Hz!1QSB$*GBWC&nE5-vapvm*&-GIDYXFld0B#nA9c0Bk?ldZ_T^jbQ5q zn2;oMVR|OtR}s^1U=UzMlFWxmG6=9B2^YYGH>;=y2un0D2yirfzQEt`9~{D^urS-) zV=<52n1MlCi-CcGdDrI){QE&FxEVmf2NT`~6Xrq)Z;o}iBg9xS*(%tDv0`$4@B+rF z$qFGZj8&UcLryX=)zwTk2p2J|t7VX9IKW=d@PMD4fq{WRnt_o~RE&wGu2z8I0DA#U zSQaK+v$-_9mPwe4i$PmQmmz>d;ZFenhX3LW3=ET5qY_LxIT z`U1G=n~P%P7#SHRPmC4QW?G7$%oz znJ{WhUX!KEsJ;1CmMN=IhiWGS1B1dF1_p!wvWyB04A&VIIRzLxG(f@z2;rNIiX0pQ z9jfY`lN}3$^*c1QIvE%W5c0Pf6*)OMJHW1*|0VXa+0S0Z}&dqC!RGIZU6XY4+6~H8gn79}j1+;m2IurPjge94{xI{sDY*LvR zW5ZmPHu)AMyO9F+f-`TcX0D`GB7y2 zV_-M{iH3`eij0f`5a9y|;maUl#tv>CUIvB+gz!})VI6@C8j;lqD+P%1KKV3c5F;I5uLzfMf5zLtT3A^$T&!+(e*B&%}s z)YncvUnlBXU&FxQ@R^|jsuhxBxp_ds2N1$042%-24BTLg7(OdBT!5Hm3K6c}tXUt- zRS!+gf8eS426Adf2;YLIW(I}?6k$$I0chGr2;V_Y+bF`Iw5_V9&cM(B7M}dOlbf+^ zGkcd16C_#wyC~oAUm6r3DzMZs*{}zc77p+?AS89*lJPz5jBS&j_nd>Jh=1@DaS0U1 quoQt1z5)`4r3i%ZH6-B!2;nnGQP1!Xo+8d62{(X+H=FdCvI78G0@3XN