From 8fed538afc2c99dd2022db97a1e8c789e882b8fb Mon Sep 17 00:00:00 2001 From: Brendan Punsky Date: Thu, 18 Jun 2026 03:39:55 -0400 Subject: [PATCH] rexcode/mips: MSA branch-on-zero/non-zero forms (BZ/BNZ) BZ/BNZ .B/.H/.W/.D/.V (branch if any/all elements zero/non-zero): a specgen branch emitter that derives the opcode+Wt bits then marks the 16-bit PC-relative offset variable, reusing the existing REL16/BRANCH_16 relocation machinery. The offset is emitted as a relocation (label target). 10 forms, opcode+Wt byte-exact vs llvm-mc and decode-clean. The R6 two-/one-register compact branches (BEQC/BNEC/BLTC/BGEC/.../BLTZC) are deferred: they share POP major opcodes disambiguated only by the rs/rt relationship, which the opcode+mask decode model can't express without operand-aware logic. 281 tests green. --- core/rexcode/mips/decoder.odin | 2 + core/rexcode/mips/encoder.odin | 3 + core/rexcode/mips/encoding_types.odin | 1 + core/rexcode/mips/mnemonic_builders.odin | 40 ++ .../rexcode/mips/tablegen/encoding_table.odin | 10 + .../tablegen/generated/decode_tables.odin | 226 ++++++----- .../tablegen/generated/encode_tables.odin | 366 +++++++++--------- core/rexcode/mips/tablegen/specgen.lua | 37 ++ .../rexcode/mips/tables/mips.encode_forms.bin | Bin 19200 -> 19400 bytes core/rexcode/mips/tables/mips.encode_runs.bin | Bin 8224 -> 8224 bytes core/rexcode/mips/tables/mips.entries.bin | Bin 19200 -> 19400 bytes core/rexcode/mips/tables/mips.idx_cop1.bin | Bin 128 -> 128 bytes core/rexcode/mips/tables/mips.idx_primary.bin | Bin 256 -> 256 bytes .../rexcode/mips/tables/mips.idx_special2.bin | Bin 256 -> 256 bytes .../rexcode/mips/tables/mips.idx_special3.bin | Bin 256 -> 256 bytes 15 files changed, 409 insertions(+), 276 deletions(-) diff --git a/core/rexcode/mips/decoder.odin b/core/rexcode/mips/decoder.odin index c588a776e..196036fd4 100644 --- a/core/rexcode/mips/decoder.odin +++ b/core/rexcode/mips/decoder.odin @@ -208,6 +208,8 @@ extract_operand_inline :: #force_inline proc "contextless" ( return reg_operand(decode_reg(word, 11, ot), ot) case .DSP_SA: return Operand{immediate = i64((word >> 21) & 0xF), kind = .IMMEDIATE, size = 1} + case .RS_RT: + return reg_operand(decode_reg(word, 16, ot), ot) // Immediates ------------------------------------------------------------ case .IMM_16: diff --git a/core/rexcode/mips/encoder.odin b/core/rexcode/mips/encoder.odin index 1ddd45424..d2b817751 100644 --- a/core/rexcode/mips/encoder.odin +++ b/core/rexcode/mips/encoder.odin @@ -402,6 +402,9 @@ pack_operand_inline :: #force_inline proc( return (u32(reg_hw(op.reg)) & 0x1F) << 11 case .DSP_SA: return (u32(op.immediate) & 0xF) << 21 + case .RS_RT: + r := u32(reg_hw(op.reg)) & 0x1F + return r << 21 | r << 16 // MSA memory operand: base GPR at 15:11, signed-10 disp at 25:16 // (caller has already scaled the displacement by element size). diff --git a/core/rexcode/mips/encoding_types.odin b/core/rexcode/mips/encoding_types.odin index 1afaf7d0a..366f8ba64 100644 --- a/core/rexcode/mips/encoding_types.odin +++ b/core/rexcode/mips/encoding_types.odin @@ -241,6 +241,7 @@ Operand_Encoding :: enum u8 { GPR_AT_6, // GPR at bits 10:6 (MSA COPY destination) GPR_AT_11, // GPR at bits 15:11 (MSA INSERT source) DSP_SA, // DSP shift amount at bits 24:21 (.PH 4-bit, .QB 3-bit) + RS_RT, // same GPR in both rs (25:21) and rt (20:16) (R6 BGEZC/BLTZC) // MSA memory operand: base GPR at bits 15:11 + signed 10-bit disp at 25:16, // scaled by element size (1/2/4/8 for B/H/W/D). diff --git a/core/rexcode/mips/mnemonic_builders.odin b/core/rexcode/mips/mnemonic_builders.odin index 4c9ee226a..e9501989e 100644 --- a/core/rexcode/mips/mnemonic_builders.odin +++ b/core/rexcode/mips/mnemonic_builders.odin @@ -1624,6 +1624,26 @@ inst_splati_w_w_w_i5 :: #force_inline proc "contextless" (dst: Register, s emit_splati_w_w_w_i5 :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, imm: i64) { append(instructions, inst_splati_w_w_w_i5(dst, src, imm)) } inst_splati_d_w_w_i5 :: #force_inline proc "contextless" (dst: Register, src: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SPLATI_D, operand_count = 3, length = 4, ops = {op_reg(dst), op_reg(src), op_imm(imm, 1), {}}} } emit_splati_d_w_w_i5 :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register, imm: i64) { append(instructions, inst_splati_d_w_w_i5(dst, src, imm)) } +inst_bz_v_w_rel :: #force_inline proc "contextless" (dst: Register, target: u32) -> Instruction { return Instruction{mnemonic = .BZ_V, operand_count = 2, length = 4, ops = {op_reg(dst), op_label(target), {}, {}}} } +emit_bz_v_w_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, target: u32) { append(instructions, inst_bz_v_w_rel(dst, target)) } +inst_bnz_v_w_rel :: #force_inline proc "contextless" (dst: Register, target: u32) -> Instruction { return Instruction{mnemonic = .BNZ_V, operand_count = 2, length = 4, ops = {op_reg(dst), op_label(target), {}, {}}} } +emit_bnz_v_w_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, target: u32) { append(instructions, inst_bnz_v_w_rel(dst, target)) } +inst_bz_b_w_rel :: #force_inline proc "contextless" (dst: Register, target: u32) -> Instruction { return Instruction{mnemonic = .BZ_B, operand_count = 2, length = 4, ops = {op_reg(dst), op_label(target), {}, {}}} } +emit_bz_b_w_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, target: u32) { append(instructions, inst_bz_b_w_rel(dst, target)) } +inst_bz_h_w_rel :: #force_inline proc "contextless" (dst: Register, target: u32) -> Instruction { return Instruction{mnemonic = .BZ_H, operand_count = 2, length = 4, ops = {op_reg(dst), op_label(target), {}, {}}} } +emit_bz_h_w_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, target: u32) { append(instructions, inst_bz_h_w_rel(dst, target)) } +inst_bz_w_w_rel :: #force_inline proc "contextless" (dst: Register, target: u32) -> Instruction { return Instruction{mnemonic = .BZ_W, operand_count = 2, length = 4, ops = {op_reg(dst), op_label(target), {}, {}}} } +emit_bz_w_w_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, target: u32) { append(instructions, inst_bz_w_w_rel(dst, target)) } +inst_bz_d_w_rel :: #force_inline proc "contextless" (dst: Register, target: u32) -> Instruction { return Instruction{mnemonic = .BZ_D, operand_count = 2, length = 4, ops = {op_reg(dst), op_label(target), {}, {}}} } +emit_bz_d_w_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, target: u32) { append(instructions, inst_bz_d_w_rel(dst, target)) } +inst_bnz_b_w_rel :: #force_inline proc "contextless" (dst: Register, target: u32) -> Instruction { return Instruction{mnemonic = .BNZ_B, operand_count = 2, length = 4, ops = {op_reg(dst), op_label(target), {}, {}}} } +emit_bnz_b_w_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, target: u32) { append(instructions, inst_bnz_b_w_rel(dst, target)) } +inst_bnz_h_w_rel :: #force_inline proc "contextless" (dst: Register, target: u32) -> Instruction { return Instruction{mnemonic = .BNZ_H, operand_count = 2, length = 4, ops = {op_reg(dst), op_label(target), {}, {}}} } +emit_bnz_h_w_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, target: u32) { append(instructions, inst_bnz_h_w_rel(dst, target)) } +inst_bnz_w_w_rel :: #force_inline proc "contextless" (dst: Register, target: u32) -> Instruction { return Instruction{mnemonic = .BNZ_W, operand_count = 2, length = 4, ops = {op_reg(dst), op_label(target), {}, {}}} } +emit_bnz_w_w_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, target: u32) { append(instructions, inst_bnz_w_w_rel(dst, target)) } +inst_bnz_d_w_rel :: #force_inline proc "contextless" (dst: Register, target: u32) -> Instruction { return Instruction{mnemonic = .BNZ_D, operand_count = 2, length = 4, ops = {op_reg(dst), op_label(target), {}, {}}} } +emit_bnz_d_w_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, target: u32) { append(instructions, inst_bnz_d_w_rel(dst, target)) } inst_nloc_b_w_w :: #force_inline proc "contextless" (dst: Register, src: Register) -> Instruction { return Instruction{mnemonic = .NLOC_B, operand_count = 2, length = 4, ops = {op_reg(dst), op_reg(src), {}, {}}} } emit_nloc_b_w_w :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register) { append(instructions, inst_nloc_b_w_w(dst, src)) } inst_nloc_h_w_w :: #force_inline proc "contextless" (dst: Register, src: Register) -> Instruction { return Instruction{mnemonic = .NLOC_H, operand_count = 2, length = 4, ops = {op_reg(dst), op_reg(src), {}, {}}} } @@ -3549,6 +3569,26 @@ inst_splati_w :: inst_splati_w_w_w_i5 emit_splati_w :: emit_splati_w_w_w_i5 inst_splati_d :: inst_splati_d_w_w_i5 emit_splati_d :: emit_splati_d_w_w_i5 +inst_bz_v :: inst_bz_v_w_rel +emit_bz_v :: emit_bz_v_w_rel +inst_bnz_v :: inst_bnz_v_w_rel +emit_bnz_v :: emit_bnz_v_w_rel +inst_bz_b :: inst_bz_b_w_rel +emit_bz_b :: emit_bz_b_w_rel +inst_bz_h :: inst_bz_h_w_rel +emit_bz_h :: emit_bz_h_w_rel +inst_bz_w :: inst_bz_w_w_rel +emit_bz_w :: emit_bz_w_w_rel +inst_bz_d :: inst_bz_d_w_rel +emit_bz_d :: emit_bz_d_w_rel +inst_bnz_b :: inst_bnz_b_w_rel +emit_bnz_b :: emit_bnz_b_w_rel +inst_bnz_h :: inst_bnz_h_w_rel +emit_bnz_h :: emit_bnz_h_w_rel +inst_bnz_w :: inst_bnz_w_w_rel +emit_bnz_w :: emit_bnz_w_w_rel +inst_bnz_d :: inst_bnz_d_w_rel +emit_bnz_d :: emit_bnz_d_w_rel inst_nloc_b :: inst_nloc_b_w_w emit_nloc_b :: emit_nloc_b_w_w inst_nloc_h :: inst_nloc_h_w_w diff --git a/core/rexcode/mips/tablegen/encoding_table.odin b/core/rexcode/mips/tablegen/encoding_table.odin index 7e794885b..b0f1c2da2 100644 --- a/core/rexcode/mips/tablegen/encoding_table.odin +++ b/core/rexcode/mips/tablegen/encoding_table.odin @@ -1629,5 +1629,15 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{ .SHRA_R_QB = { {.SHRA_R_QB, {.GPR,.GPR,.IMM5,.NONE}, {.RD,.RT,.DSP_SA,.NONE}, 0x7C000153, 0xFF0007FF, .DSP_R2, {}} }, .SHRA_R_PH = { {.SHRA_R_PH, {.GPR,.GPR,.IMM5,.NONE}, {.RD,.RT,.DSP_SA,.NONE}, 0x7C000353, 0xFE0007FF, .DSP_R2, {}} }, .SHRL_PH = { {.SHRL_PH, {.GPR,.GPR,.IMM5,.NONE}, {.RD,.RT,.DSP_SA,.NONE}, 0x7C000653, 0xFE0007FF, .DSP_R2, {}} }, + .BZ_B = { {.BZ_B, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47000000, 0xFFE00000, .MSA, {}} }, + .BZ_H = { {.BZ_H, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47200000, 0xFFE00000, .MSA, {}} }, + .BZ_W = { {.BZ_W, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47400000, 0xFFE00000, .MSA, {}} }, + .BZ_D = { {.BZ_D, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47600000, 0xFFE00000, .MSA, {}} }, + .BZ_V = { {.BZ_V, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x45600000, 0xFFE00000, .MSA, {}} }, + .BNZ_B = { {.BNZ_B, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47800000, 0xFFE00000, .MSA, {}} }, + .BNZ_H = { {.BNZ_H, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47A00000, 0xFFE00000, .MSA, {}} }, + .BNZ_W = { {.BNZ_W, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47C00000, 0xFFE00000, .MSA, {}} }, + .BNZ_D = { {.BNZ_D, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47E00000, 0xFFE00000, .MSA, {}} }, + .BNZ_V = { {.BNZ_V, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x45E00000, 0xFFE00000, .MSA, {}} }, // SPECGEN:END } diff --git a/core/rexcode/mips/tablegen/generated/decode_tables.odin b/core/rexcode/mips/tablegen/generated/decode_tables.odin index f92217d61..3800c55f5 100644 --- a/core/rexcode/mips/tablegen/generated/decode_tables.odin +++ b/core/rexcode/mips/tablegen/generated/decode_tables.odin @@ -8,7 +8,7 @@ package rexcode_mips_generated import lib "../.." @(rodata) -DECODE_ENTRIES := [960]lib.Decode_Entry{ +DECODE_ENTRIES := [970]lib.Decode_Entry{ { .NOP, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x00000000, 0xFFFFFFFF, .MIPS_I, {} }, { .SSNOP, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x00000040, 0xFFFFFFFF, .MIPS32_R1, {} }, { .EHB, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x000000C0, 0xFFFFFFFF, .MIPS32_R2, {} }, @@ -156,7 +156,9 @@ DECODE_ENTRIES := [960]lib.Decode_Entry{ { .BC1FL, {.FCC,.REL16,.NONE,.NONE}, {.FCC_BC,.BRANCH_16,.NONE,.NONE}, 0x45020000, 0xFFE30000, .MIPS_II, {delay_slot=true, likely=true} }, { .BC1TL, {.FCC,.REL16,.NONE,.NONE}, {.FCC_BC,.BRANCH_16,.NONE,.NONE}, 0x45030000, 0xFFE30000, .MIPS_II, {delay_slot=true, likely=true} }, { .BC1EQZ, {.FPR_S,.REL16,.NONE,.NONE}, {.FT,.BRANCH_16,.NONE,.NONE}, 0x45200000, 0xFFE00000, .MIPS32_R6, {compact=true} }, + { .BZ_V, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x45600000, 0xFFE00000, .MSA, {} }, { .BC1NEZ, {.FPR_S,.REL16,.NONE,.NONE}, {.FT,.BRANCH_16,.NONE,.NONE}, 0x45A00000, 0xFFE00000, .MIPS32_R6, {compact=true} }, + { .BNZ_V, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x45E00000, 0xFFE00000, .MSA, {} }, { .SQRT_S, {.FPR_S,.FPR_S,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46000004, 0xFFFF003F, .MIPS_II, {} }, { .ABS_S, {.FPR_S,.FPR_S,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46000005, 0xFFFF003F, .FPU, {} }, { .NEG_S, {.FPR_S,.FPR_S,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46000007, 0xFFFF003F, .FPU, {} }, @@ -268,6 +270,14 @@ DECODE_ENTRIES := [960]lib.Decode_Entry{ { .ADD_PS, {.FPR_PS,.FPR_PS,.FPR_PS,.NONE}, {.FD,.FS,.FT,.NONE}, 0x46C00000, 0xFFE0003F, .MIPS_V, {} }, { .SUB_PS, {.FPR_PS,.FPR_PS,.FPR_PS,.NONE}, {.FD,.FS,.FT,.NONE}, 0x46C00001, 0xFFE0003F, .MIPS_V, {} }, { .MUL_PS, {.FPR_PS,.FPR_PS,.FPR_PS,.NONE}, {.FD,.FS,.FT,.NONE}, 0x46C00002, 0xFFE0003F, .MIPS_V, {} }, + { .BZ_B, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47000000, 0xFFE00000, .MSA, {} }, + { .BZ_H, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47200000, 0xFFE00000, .MSA, {} }, + { .BZ_W, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47400000, 0xFFE00000, .MSA, {} }, + { .BZ_D, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47600000, 0xFFE00000, .MSA, {} }, + { .BNZ_B, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47800000, 0xFFE00000, .MSA, {} }, + { .BNZ_H, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47A00000, 0xFFE00000, .MSA, {} }, + { .BNZ_W, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47C00000, 0xFFE00000, .MSA, {} }, + { .BNZ_D, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47E00000, 0xFFE00000, .MSA, {} }, { .MFC2, {.GPR,.CP2_REG,.NONE,.NONE}, {.RT,.RD,.NONE,.NONE}, 0x48000000, 0xFFE007FF, .GTE_PS1, {} }, { .MTC2, {.GPR,.CP2_REG,.NONE,.NONE}, {.RT,.RD,.NONE,.NONE}, 0x48800000, 0xFFE007FF, .GTE_PS1, {} }, { .CFC2, {.GPR,.CP2_CTRL,.NONE,.NONE}, {.RT,.RD,.NONE,.NONE}, 0x48400000, 0xFFE007FF, .GTE_PS1, {} }, @@ -990,53 +1000,53 @@ DECODE_INDEX_PRIMARY := [64]lib.Decode_Index{ 0x0E = { 116, 1}, 0x0F = { 117, 2}, 0x10 = { 119, 15}, - 0x11 = { 134, 125}, - 0x12 = { 259, 36}, - 0x13 = { 295, 13}, - 0x14 = { 308, 1}, - 0x15 = { 309, 1}, - 0x16 = { 310, 1}, - 0x17 = { 311, 1}, - 0x18 = { 312, 13}, - 0x19 = { 325, 15}, - 0x1A = { 340, 1}, - 0x1B = { 341, 13}, - 0x1C = { 354, 109}, - 0x1D = { 463, 1}, - 0x1E = { 464, 228}, - 0x1F = { 692, 123}, - 0x20 = { 815, 1}, - 0x21 = { 816, 1}, - 0x22 = { 817, 1}, - 0x23 = { 818, 1}, - 0x24 = { 819, 1}, - 0x25 = { 820, 1}, - 0x26 = { 821, 1}, - 0x27 = { 822, 1}, - 0x28 = { 823, 1}, - 0x29 = { 824, 1}, - 0x2A = { 825, 1}, - 0x2B = { 826, 1}, - 0x2C = { 827, 1}, - 0x2D = { 828, 1}, - 0x2E = { 829, 1}, - 0x2F = { 830, 1}, - 0x30 = { 831, 1}, - 0x31 = { 832, 1}, - 0x32 = { 833, 3}, - 0x33 = { 836, 1}, - 0x34 = { 837, 63}, - 0x35 = { 900, 3}, - 0x36 = { 903, 5}, - 0x37 = { 908, 6}, - 0x38 = { 914, 1}, - 0x39 = { 915, 1}, - 0x3A = { 916, 3}, - 0x3B = { 919, 2}, - 0x3C = { 921, 27}, - 0x3D = { 948, 3}, - 0x3E = { 951, 5}, - 0x3F = { 956, 4}, + 0x11 = { 134, 135}, + 0x12 = { 269, 36}, + 0x13 = { 305, 13}, + 0x14 = { 318, 1}, + 0x15 = { 319, 1}, + 0x16 = { 320, 1}, + 0x17 = { 321, 1}, + 0x18 = { 322, 13}, + 0x19 = { 335, 15}, + 0x1A = { 350, 1}, + 0x1B = { 351, 13}, + 0x1C = { 364, 109}, + 0x1D = { 473, 1}, + 0x1E = { 474, 228}, + 0x1F = { 702, 123}, + 0x20 = { 825, 1}, + 0x21 = { 826, 1}, + 0x22 = { 827, 1}, + 0x23 = { 828, 1}, + 0x24 = { 829, 1}, + 0x25 = { 830, 1}, + 0x26 = { 831, 1}, + 0x27 = { 832, 1}, + 0x28 = { 833, 1}, + 0x29 = { 834, 1}, + 0x2A = { 835, 1}, + 0x2B = { 836, 1}, + 0x2C = { 837, 1}, + 0x2D = { 838, 1}, + 0x2E = { 839, 1}, + 0x2F = { 840, 1}, + 0x30 = { 841, 1}, + 0x31 = { 842, 1}, + 0x32 = { 843, 3}, + 0x33 = { 846, 1}, + 0x34 = { 847, 63}, + 0x35 = { 910, 3}, + 0x36 = { 913, 5}, + 0x37 = { 918, 6}, + 0x38 = { 924, 1}, + 0x39 = { 925, 1}, + 0x3A = { 926, 3}, + 0x3B = { 929, 2}, + 0x3C = { 931, 27}, + 0x3D = { 958, 3}, + 0x3E = { 961, 5}, + 0x3F = { 966, 4}, } @(rodata) @@ -1140,68 +1150,78 @@ DECODE_INDEX_COP1 := [32]lib.Decode_Index{ 0x07 = { 141, 1}, 0x08 = { 142, 4}, 0x09 = { 146, 1}, - 0x0D = { 147, 1}, - 0x10 = { 148, 41}, - 0x11 = { 189, 42}, - 0x14 = { 231, 4}, - 0x15 = { 235, 2}, - 0x16 = { 237, 22}, + 0x0B = { 147, 1}, + 0x0D = { 148, 1}, + 0x0F = { 149, 1}, + 0x10 = { 150, 41}, + 0x11 = { 191, 42}, + 0x14 = { 233, 4}, + 0x15 = { 237, 2}, + 0x16 = { 239, 22}, + 0x18 = { 261, 1}, + 0x19 = { 262, 1}, + 0x1A = { 263, 1}, + 0x1B = { 264, 1}, + 0x1C = { 265, 1}, + 0x1D = { 266, 1}, + 0x1E = { 267, 1}, + 0x1F = { 268, 1}, } @(rodata) DECODE_INDEX_SPECIAL2 := [64]lib.Decode_Index{ - 0x00 = { 354, 1}, - 0x01 = { 355, 1}, - 0x02 = { 356, 1}, - 0x04 = { 357, 2}, - 0x05 = { 359, 1}, - 0x08 = { 360, 25}, - 0x09 = { 385, 26}, - 0x10 = { 411, 1}, - 0x11 = { 412, 1}, - 0x12 = { 413, 1}, - 0x13 = { 414, 1}, - 0x18 = { 415, 1}, - 0x19 = { 416, 1}, - 0x1A = { 417, 1}, - 0x1B = { 418, 1}, - 0x20 = { 419, 2}, - 0x21 = { 421, 2}, - 0x24 = { 423, 1}, - 0x25 = { 424, 1}, - 0x28 = { 425, 17}, - 0x29 = { 442, 8}, - 0x30 = { 450, 5}, - 0x31 = { 455, 1}, - 0x34 = { 456, 1}, - 0x36 = { 457, 1}, - 0x37 = { 458, 1}, - 0x3C = { 459, 1}, - 0x3E = { 460, 1}, - 0x3F = { 461, 2}, + 0x00 = { 364, 1}, + 0x01 = { 365, 1}, + 0x02 = { 366, 1}, + 0x04 = { 367, 2}, + 0x05 = { 369, 1}, + 0x08 = { 370, 25}, + 0x09 = { 395, 26}, + 0x10 = { 421, 1}, + 0x11 = { 422, 1}, + 0x12 = { 423, 1}, + 0x13 = { 424, 1}, + 0x18 = { 425, 1}, + 0x19 = { 426, 1}, + 0x1A = { 427, 1}, + 0x1B = { 428, 1}, + 0x20 = { 429, 2}, + 0x21 = { 431, 2}, + 0x24 = { 433, 1}, + 0x25 = { 434, 1}, + 0x28 = { 435, 17}, + 0x29 = { 452, 8}, + 0x30 = { 460, 5}, + 0x31 = { 465, 1}, + 0x34 = { 466, 1}, + 0x36 = { 467, 1}, + 0x37 = { 468, 1}, + 0x3C = { 469, 1}, + 0x3E = { 470, 1}, + 0x3F = { 471, 2}, } @(rodata) DECODE_INDEX_SPECIAL3 := [64]lib.Decode_Index{ - 0x00 = { 692, 2}, - 0x01 = { 694, 1}, - 0x02 = { 695, 1}, - 0x03 = { 696, 1}, - 0x04 = { 697, 1}, - 0x05 = { 698, 1}, - 0x06 = { 699, 1}, - 0x07 = { 700, 1}, - 0x0A = { 701, 3}, - 0x0C = { 704, 1}, - 0x0F = { 705, 8}, - 0x10 = { 713, 22}, - 0x11 = { 735, 15}, - 0x12 = { 750, 15}, - 0x13 = { 765, 22}, - 0x20 = { 787, 5}, - 0x24 = { 792, 4}, - 0x30 = { 796, 9}, - 0x38 = { 805, 9}, - 0x3B = { 814, 1}, + 0x00 = { 702, 2}, + 0x01 = { 704, 1}, + 0x02 = { 705, 1}, + 0x03 = { 706, 1}, + 0x04 = { 707, 1}, + 0x05 = { 708, 1}, + 0x06 = { 709, 1}, + 0x07 = { 710, 1}, + 0x0A = { 711, 3}, + 0x0C = { 714, 1}, + 0x0F = { 715, 8}, + 0x10 = { 723, 22}, + 0x11 = { 745, 15}, + 0x12 = { 760, 15}, + 0x13 = { 775, 22}, + 0x20 = { 797, 5}, + 0x24 = { 802, 4}, + 0x30 = { 806, 9}, + 0x38 = { 815, 9}, + 0x3B = { 824, 1}, } diff --git a/core/rexcode/mips/tablegen/generated/encode_tables.odin b/core/rexcode/mips/tablegen/generated/encode_tables.odin index 6e0404f5c..467d9d9aa 100644 --- a/core/rexcode/mips/tablegen/generated/encode_tables.odin +++ b/core/rexcode/mips/tablegen/generated/encode_tables.odin @@ -8,7 +8,7 @@ package rexcode_mips_generated import lib "../.." @(rodata) -ENCODE_FORMS := [960]lib.Encoding{ +ENCODE_FORMS := [970]lib.Encoding{ // .ADD { .ADD, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS,.RT,.NONE}, 0x00000020, 0xFC0007FF, .MIPS_I, {} }, // .ADDU @@ -1605,6 +1605,26 @@ ENCODE_FORMS := [960]lib.Encoding{ { .SPLATI_W, {.MSA_VEC,.MSA_VEC,.IMM5,.NONE}, {.WD,.WS,.MSA_ELM_IDX,.NONE}, 0x78700019, 0xFFFC003F, .MSA, {} }, // .SPLATI_D { .SPLATI_D, {.MSA_VEC,.MSA_VEC,.IMM5,.NONE}, {.WD,.WS,.MSA_ELM_IDX,.NONE}, 0x78780019, 0xFFFE003F, .MSA, {} }, + // .BZ_V + { .BZ_V, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x45600000, 0xFFE00000, .MSA, {} }, + // .BNZ_V + { .BNZ_V, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x45E00000, 0xFFE00000, .MSA, {} }, + // .BZ_B + { .BZ_B, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47000000, 0xFFE00000, .MSA, {} }, + // .BZ_H + { .BZ_H, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47200000, 0xFFE00000, .MSA, {} }, + // .BZ_W + { .BZ_W, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47400000, 0xFFE00000, .MSA, {} }, + // .BZ_D + { .BZ_D, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47600000, 0xFFE00000, .MSA, {} }, + // .BNZ_B + { .BNZ_B, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47800000, 0xFFE00000, .MSA, {} }, + // .BNZ_H + { .BNZ_H, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47A00000, 0xFFE00000, .MSA, {} }, + // .BNZ_W + { .BNZ_W, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47C00000, 0xFFE00000, .MSA, {} }, + // .BNZ_D + { .BNZ_D, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47E00000, 0xFFE00000, .MSA, {} }, // .NLOC_B { .NLOC_B, {.MSA_VEC,.MSA_VEC,.NONE,.NONE}, {.WD,.WS,.NONE,.NONE}, 0x7B08001E, 0xFFFF003F, .MSA, {} }, // .NLOC_H @@ -2789,176 +2809,176 @@ ENCODE_RUNS := [lib.Mnemonic]lib.Encode_Run{ .SPLATI_H = { 795, 1}, .SPLATI_W = { 796, 1}, .SPLATI_D = { 797, 1}, - .BZ_V = { 798, 0}, - .BNZ_V = { 798, 0}, - .BZ_B = { 798, 0}, - .BZ_H = { 798, 0}, - .BZ_W = { 798, 0}, - .BZ_D = { 798, 0}, - .BNZ_B = { 798, 0}, - .BNZ_H = { 798, 0}, - .BNZ_W = { 798, 0}, - .BNZ_D = { 798, 0}, - .NLOC_B = { 798, 1}, - .NLOC_H = { 799, 1}, - .NLOC_W = { 800, 1}, - .NLOC_D = { 801, 1}, - .NLZC_B = { 802, 1}, - .NLZC_H = { 803, 1}, - .NLZC_W = { 804, 1}, - .NLZC_D = { 805, 1}, - .PCNT_B = { 806, 1}, - .PCNT_H = { 807, 1}, - .PCNT_W = { 808, 1}, - .PCNT_D = { 809, 1}, - .VMOV_S = { 810, 1}, - .VMOV_P = { 811, 1}, - .VMOV_T = { 812, 1}, - .VMOV_Q = { 813, 1}, - .LV_S = { 814, 1}, - .LV_Q = { 815, 1}, - .SV_S = { 816, 1}, - .SV_Q = { 817, 1}, - .LVL_Q = { 818, 1}, - .LVR_Q = { 819, 1}, - .SVL_Q = { 820, 1}, - .SVR_Q = { 821, 1}, - .VIIM_S = { 822, 1}, - .VFIM_S = { 823, 1}, - .VADD_S = { 824, 1}, - .VADD_P = { 825, 1}, - .VADD_T = { 826, 1}, - .VADD_Q = { 827, 1}, - .VSUB_S = { 828, 1}, - .VSUB_P = { 829, 1}, - .VSUB_T = { 830, 1}, - .VSUB_Q = { 831, 1}, - .VMUL_S = { 832, 1}, - .VMUL_P = { 833, 1}, - .VMUL_T = { 834, 1}, - .VMUL_Q = { 835, 1}, - .VDIV_S = { 836, 1}, - .VDIV_P = { 837, 1}, - .VDIV_T = { 838, 1}, - .VDIV_Q = { 839, 1}, - .VABS_S = { 840, 1}, - .VABS_P = { 841, 1}, - .VABS_T = { 842, 1}, - .VABS_Q = { 843, 1}, - .VNEG_S = { 844, 1}, - .VNEG_P = { 845, 1}, - .VNEG_T = { 846, 1}, - .VNEG_Q = { 847, 1}, - .VSQRT_S = { 848, 1}, - .VRCP_S = { 849, 1}, - .VRCP_P = { 850, 1}, - .VRCP_T = { 851, 1}, - .VRCP_Q = { 852, 1}, - .VRSQ_S = { 853, 1}, - .VRSQ_P = { 854, 1}, - .VRSQ_T = { 855, 1}, - .VRSQ_Q = { 856, 1}, - .VDOT_P = { 857, 1}, - .VDOT_T = { 858, 1}, - .VDOT_Q = { 859, 1}, - .VSCL_P = { 860, 1}, - .VSCL_T = { 861, 1}, - .VSCL_Q = { 862, 1}, - .VHDP_P = { 863, 1}, - .VHDP_T = { 864, 1}, - .VHDP_Q = { 865, 1}, - .VAVG_P = { 866, 1}, - .VAVG_T = { 867, 1}, - .VAVG_Q = { 868, 1}, - .VFAD_P = { 869, 1}, - .VFAD_T = { 870, 1}, - .VFAD_Q = { 871, 1}, - .VMMUL_P = { 872, 1}, - .VMMUL_T = { 873, 1}, - .VMMUL_Q = { 874, 1}, - .VTFM2_P = { 875, 1}, - .VTFM3_T = { 876, 1}, - .VTFM4_Q = { 877, 1}, - .VHTFM2_P = { 878, 1}, - .VHTFM3_T = { 879, 1}, - .VHTFM4_Q = { 880, 1}, - .VMSCL_P = { 881, 1}, - .VMSCL_T = { 882, 1}, - .VMSCL_Q = { 883, 1}, - .VMMOV_P = { 884, 1}, - .VMMOV_T = { 885, 1}, - .VMMOV_Q = { 886, 1}, - .VMIDT_P = { 887, 1}, - .VMIDT_T = { 888, 1}, - .VMIDT_Q = { 889, 1}, - .VMZERO_P = { 890, 1}, - .VMZERO_T = { 891, 1}, - .VMZERO_Q = { 892, 1}, - .VMONE_P = { 893, 1}, - .VMONE_T = { 894, 1}, - .VMONE_Q = { 895, 1}, - .VCRS_T = { 896, 1}, - .VCRSP_T = { 897, 1}, - .VQMUL_Q = { 898, 1}, - .VCMP_S = { 899, 1}, - .VCMP_P = { 900, 1}, - .VCMP_T = { 901, 1}, - .VCMP_Q = { 902, 1}, - .VMIN_S = { 903, 1}, - .VMIN_P = { 904, 1}, - .VMIN_T = { 905, 1}, - .VMIN_Q = { 906, 1}, - .VMAX_S = { 907, 1}, - .VMAX_P = { 908, 1}, - .VMAX_T = { 909, 1}, - .VMAX_Q = { 910, 1}, - .VSIN_S = { 911, 1}, - .VCOS_S = { 912, 1}, - .VEXP2_S = { 913, 1}, - .VLOG2_S = { 914, 1}, - .VASIN_S = { 915, 1}, - .VNRCP_S = { 916, 1}, - .VNSIN_S = { 917, 1}, - .VREXP2_S = { 918, 1}, - .VSGN_S = { 919, 1}, - .VI2F_S = { 920, 1}, - .VI2F_P = { 921, 1}, - .VI2F_T = { 922, 1}, - .VI2F_Q = { 923, 1}, - .VF2IN_S = { 924, 1}, - .VF2IN_P = { 925, 1}, - .VF2IN_T = { 926, 1}, - .VF2IN_Q = { 927, 1}, - .VF2IZ_S = { 928, 1}, - .VF2IZ_P = { 929, 1}, - .VF2IZ_T = { 930, 1}, - .VF2IZ_Q = { 931, 1}, - .VF2IU_S = { 932, 1}, - .VF2IU_P = { 933, 1}, - .VF2IU_T = { 934, 1}, - .VF2IU_Q = { 935, 1}, - .VF2ID_S = { 936, 1}, - .VF2ID_P = { 937, 1}, - .VF2ID_T = { 938, 1}, - .VF2ID_Q = { 939, 1}, - .VF2H_P = { 940, 1}, - .VH2F_S = { 941, 1}, - .VFLUSH = { 942, 1}, - .VSYNC = { 943, 1}, - .VNOP = { 944, 1}, - .VPFXS = { 945, 1}, - .VPFXT = { 946, 1}, - .VPFXD = { 947, 1}, - .VCST_S = { 948, 1}, - .VCST_P = { 949, 1}, - .VCST_T = { 950, 1}, - .VCST_Q = { 951, 1}, - .MFV = { 952, 1}, - .MTV = { 953, 1}, - .MFVC = { 954, 1}, - .MTVC = { 955, 1}, - .BVF = { 956, 1}, - .BVT = { 957, 1}, - .BVFL = { 958, 1}, - .BVTL = { 959, 1}, + .BZ_V = { 798, 1}, + .BNZ_V = { 799, 1}, + .BZ_B = { 800, 1}, + .BZ_H = { 801, 1}, + .BZ_W = { 802, 1}, + .BZ_D = { 803, 1}, + .BNZ_B = { 804, 1}, + .BNZ_H = { 805, 1}, + .BNZ_W = { 806, 1}, + .BNZ_D = { 807, 1}, + .NLOC_B = { 808, 1}, + .NLOC_H = { 809, 1}, + .NLOC_W = { 810, 1}, + .NLOC_D = { 811, 1}, + .NLZC_B = { 812, 1}, + .NLZC_H = { 813, 1}, + .NLZC_W = { 814, 1}, + .NLZC_D = { 815, 1}, + .PCNT_B = { 816, 1}, + .PCNT_H = { 817, 1}, + .PCNT_W = { 818, 1}, + .PCNT_D = { 819, 1}, + .VMOV_S = { 820, 1}, + .VMOV_P = { 821, 1}, + .VMOV_T = { 822, 1}, + .VMOV_Q = { 823, 1}, + .LV_S = { 824, 1}, + .LV_Q = { 825, 1}, + .SV_S = { 826, 1}, + .SV_Q = { 827, 1}, + .LVL_Q = { 828, 1}, + .LVR_Q = { 829, 1}, + .SVL_Q = { 830, 1}, + .SVR_Q = { 831, 1}, + .VIIM_S = { 832, 1}, + .VFIM_S = { 833, 1}, + .VADD_S = { 834, 1}, + .VADD_P = { 835, 1}, + .VADD_T = { 836, 1}, + .VADD_Q = { 837, 1}, + .VSUB_S = { 838, 1}, + .VSUB_P = { 839, 1}, + .VSUB_T = { 840, 1}, + .VSUB_Q = { 841, 1}, + .VMUL_S = { 842, 1}, + .VMUL_P = { 843, 1}, + .VMUL_T = { 844, 1}, + .VMUL_Q = { 845, 1}, + .VDIV_S = { 846, 1}, + .VDIV_P = { 847, 1}, + .VDIV_T = { 848, 1}, + .VDIV_Q = { 849, 1}, + .VABS_S = { 850, 1}, + .VABS_P = { 851, 1}, + .VABS_T = { 852, 1}, + .VABS_Q = { 853, 1}, + .VNEG_S = { 854, 1}, + .VNEG_P = { 855, 1}, + .VNEG_T = { 856, 1}, + .VNEG_Q = { 857, 1}, + .VSQRT_S = { 858, 1}, + .VRCP_S = { 859, 1}, + .VRCP_P = { 860, 1}, + .VRCP_T = { 861, 1}, + .VRCP_Q = { 862, 1}, + .VRSQ_S = { 863, 1}, + .VRSQ_P = { 864, 1}, + .VRSQ_T = { 865, 1}, + .VRSQ_Q = { 866, 1}, + .VDOT_P = { 867, 1}, + .VDOT_T = { 868, 1}, + .VDOT_Q = { 869, 1}, + .VSCL_P = { 870, 1}, + .VSCL_T = { 871, 1}, + .VSCL_Q = { 872, 1}, + .VHDP_P = { 873, 1}, + .VHDP_T = { 874, 1}, + .VHDP_Q = { 875, 1}, + .VAVG_P = { 876, 1}, + .VAVG_T = { 877, 1}, + .VAVG_Q = { 878, 1}, + .VFAD_P = { 879, 1}, + .VFAD_T = { 880, 1}, + .VFAD_Q = { 881, 1}, + .VMMUL_P = { 882, 1}, + .VMMUL_T = { 883, 1}, + .VMMUL_Q = { 884, 1}, + .VTFM2_P = { 885, 1}, + .VTFM3_T = { 886, 1}, + .VTFM4_Q = { 887, 1}, + .VHTFM2_P = { 888, 1}, + .VHTFM3_T = { 889, 1}, + .VHTFM4_Q = { 890, 1}, + .VMSCL_P = { 891, 1}, + .VMSCL_T = { 892, 1}, + .VMSCL_Q = { 893, 1}, + .VMMOV_P = { 894, 1}, + .VMMOV_T = { 895, 1}, + .VMMOV_Q = { 896, 1}, + .VMIDT_P = { 897, 1}, + .VMIDT_T = { 898, 1}, + .VMIDT_Q = { 899, 1}, + .VMZERO_P = { 900, 1}, + .VMZERO_T = { 901, 1}, + .VMZERO_Q = { 902, 1}, + .VMONE_P = { 903, 1}, + .VMONE_T = { 904, 1}, + .VMONE_Q = { 905, 1}, + .VCRS_T = { 906, 1}, + .VCRSP_T = { 907, 1}, + .VQMUL_Q = { 908, 1}, + .VCMP_S = { 909, 1}, + .VCMP_P = { 910, 1}, + .VCMP_T = { 911, 1}, + .VCMP_Q = { 912, 1}, + .VMIN_S = { 913, 1}, + .VMIN_P = { 914, 1}, + .VMIN_T = { 915, 1}, + .VMIN_Q = { 916, 1}, + .VMAX_S = { 917, 1}, + .VMAX_P = { 918, 1}, + .VMAX_T = { 919, 1}, + .VMAX_Q = { 920, 1}, + .VSIN_S = { 921, 1}, + .VCOS_S = { 922, 1}, + .VEXP2_S = { 923, 1}, + .VLOG2_S = { 924, 1}, + .VASIN_S = { 925, 1}, + .VNRCP_S = { 926, 1}, + .VNSIN_S = { 927, 1}, + .VREXP2_S = { 928, 1}, + .VSGN_S = { 929, 1}, + .VI2F_S = { 930, 1}, + .VI2F_P = { 931, 1}, + .VI2F_T = { 932, 1}, + .VI2F_Q = { 933, 1}, + .VF2IN_S = { 934, 1}, + .VF2IN_P = { 935, 1}, + .VF2IN_T = { 936, 1}, + .VF2IN_Q = { 937, 1}, + .VF2IZ_S = { 938, 1}, + .VF2IZ_P = { 939, 1}, + .VF2IZ_T = { 940, 1}, + .VF2IZ_Q = { 941, 1}, + .VF2IU_S = { 942, 1}, + .VF2IU_P = { 943, 1}, + .VF2IU_T = { 944, 1}, + .VF2IU_Q = { 945, 1}, + .VF2ID_S = { 946, 1}, + .VF2ID_P = { 947, 1}, + .VF2ID_T = { 948, 1}, + .VF2ID_Q = { 949, 1}, + .VF2H_P = { 950, 1}, + .VH2F_S = { 951, 1}, + .VFLUSH = { 952, 1}, + .VSYNC = { 953, 1}, + .VNOP = { 954, 1}, + .VPFXS = { 955, 1}, + .VPFXT = { 956, 1}, + .VPFXD = { 957, 1}, + .VCST_S = { 958, 1}, + .VCST_P = { 959, 1}, + .VCST_T = { 960, 1}, + .VCST_Q = { 961, 1}, + .MFV = { 962, 1}, + .MTV = { 963, 1}, + .MFVC = { 964, 1}, + .MTVC = { 965, 1}, + .BVF = { 966, 1}, + .BVT = { 967, 1}, + .BVFL = { 968, 1}, + .BVTL = { 969, 1}, } diff --git a/core/rexcode/mips/tablegen/specgen.lua b/core/rexcode/mips/tablegen/specgen.lua index 20a133d77..d498ed525 100644 --- a/core/rexcode/mips/tablegen/specgen.lua +++ b/core/rexcode/mips/tablegen/specgen.lua @@ -272,6 +272,43 @@ for _, b in ipairs({{"SHRA_QB","shra.qb",7},{"SHRA_R_QB","shra_r.qb",7},{"SHRA_R if r then sections[#sections+1]=r end end +-- ---- Branches: derive bits/regs, then mark the PC-relative offset variable. +-- Compact (R6) branches need the r6 ISA, so each family passes its own mattr. +local function bword(line, mattr) + local p = io.popen(string.format("printf '%%s\\n' '%s' | llvm-mc --assemble --triple=mips --mattr=%s --show-encoding 2>/dev/null", line, mattr)) + local out = p:read("*a"); p:close() + local b1,b2,b3,b4 = out:match("0x(%x%x),0x(%x%x),0x(%x%x),0x(%x%x)") + if not b1 then return nil end + return tonumber(b1..b2..b3..b4, 16) +end +local function branch_block(mnem, ops, enc, feat, asm, maxes, offbits, mattr) + local zero={}; for i=1,#maxes do zero[i]=0 end + local b0 = bword(asm(zero), mattr) + if not b0 then skips[#skips+1]=mnem; return end + local vs={} + for i=1,#maxes do + local v={}; for j=1,#maxes do v[j]=0 end; v[i]=maxes[i] + local w=bword(asm(v), mattr); if not w then skips[#skips+1]=mnem; return end; vs[#vs+1]=w + end + local m = bit.band(mask_of(b0,vs), bit.bnot((2^offbits)-1)) -- offset field = variable + n_forms=n_forms+1 + sections[#sections+1]=string.format(" .%s = { {.%s, %s, %s, 0x%s, 0x%s, .%s, {}} },", + mnem, mnem, ops, enc, bit.tohex(b0):upper(), bit.tohex(m):upper(), feat) +end + +-- NOTE: the R6 two-/one-register compact branches (BEQC/BNEC/BLTC/BGEC/BLTUC/ +-- BGEUC/BLEZC/BGTZC/BGEZC/BLTZC) are intentionally NOT generated here. They +-- pack into shared "POP" major opcodes (e.g. BGEC/BLTC/BLEZC/BGEZC all live in +-- 0x58/0x5C) and are disambiguated only by the rs/rt *relationship* (rs==rt, +-- rs==0, rs*zi|Ihb3>g?y;bOWFF(U>BH3o(XK8VG75JBV34%QOP^%2a%QVa|# zybKHs3<<6b3=jSbGDISYJ%EZuA&D`#L)1khi77zEVvxifpklE|VhK>OIEa`V*y0AL eU_3++EVckDmVhL704kPxov~pWX+x;bOWFF+&ChH3o(XK8VG75J98O4%QOPn-%O=@BjeB CyBZAu diff --git a/core/rexcode/mips/tables/mips.encode_runs.bin b/core/rexcode/mips/tables/mips.encode_runs.bin index d7a2776ad328dd37148faf5d3623d3164f5775fa..66eecc885d90f3f341be969574c5d982ef5df7ca 100644 GIT binary patch delta 93 zcmZ4Bu)tx%5vk20(mbpI2bdWc7#SEC4npZeQ2H>GJ_4nWLg`~r`Z$z60i{nuX#nbz B3}*lU delta 86 ecmZ4Bu)tx%5h+gw1_lN>W)Mjsy?L*cFe?CII|gF_ diff --git a/core/rexcode/mips/tables/mips.entries.bin b/core/rexcode/mips/tables/mips.entries.bin index edb71357cc2aae256a6f457a32b32078445294f7..b4e7550766e8034114aa6a6e1e15ed052ab83f42 100644 GIT binary patch delta 389 zcmZpe#&}{ni^ ziwQDpp1{3^qdp2rhQS?TLNtm-P=t$VLd1+17?j{* zS`aZ~1_ougm^MVrfPp~;E~Wz!Gh|>;g^TGz#Ecji)EF2l_#hVRK?IFAe=rpg1pr$% BLdXCB delta 171 zcmX>xov~pWhW89&U_L7&BLf>F eBLh1lBLfE`BLgQRBLf#BBLg=hBLfd3BLe^=R|u~F literal 128 zcmZo;U}R`#U}WfEU}WfIU}WfGU}WfKU}WfFU}WfJU}WfHU}2cVz{r3MCL{5uFlaLD YWzd34KWAWJc+J4X@RmUgE{2Z*0A`;GjQ{`u diff --git a/core/rexcode/mips/tables/mips.idx_primary.bin b/core/rexcode/mips/tables/mips.idx_primary.bin index f33214678b2b8eb386f4979a9006b0ed9573b083..bb16c344583d6daf63d30ada6328a44f39079f8a 100644 GIT binary patch delta 162 zcmZo*YG9h+X4%fb%c#O&$jHlJ$H>TF&&bH&z{tqp$jHdx#K_Cw&&baZ$H>SK&&bP= z!2#Obm;er5W}y PGcz1yW@R|W%)$TwV6hiB delta 162 zcmZo*YG9h+mRQTc%&5Yk&dAGP!pO*A%E-uI#>mKE&dA7M!N|+t%E-?U!pO)F%E-%* z#F)!)o{^E^0^<{gElkx6`pk?B2F#2MhRlo%M$C*1#>|WiCd`Zsrp$~CX3UHX=FE%? z7R-zj>y^!z8C;kd8C;p|8CsZ`8QPgy8G4x67$z|@GE8P>WSGLt%rKpqiD4$QG{Y8V OW`^y|tPFdYSr`DEqZK&- diff --git a/core/rexcode/mips/tables/mips.idx_special2.bin b/core/rexcode/mips/tables/mips.idx_special2.bin index de9b3a914cbb80c37247c5b63f8cc055b23f6bce..054c71f4f2824a203e1ee6c85ab044910f15cb24 100644 GIT binary patch literal 256 zcmc~{WMs%?WMs%=WMlw=d`2dQLMR)=FJhEr=w_4xF|p#MjEoG+7#SIsGcq!)K+*?O zypoZTVHG1I!)iuGhBa8^*D^9OtY>6`DQDQo$jGn>N!?~fL53rY9B_Gb#u-LdhKoq* cFG1Ot85tR_K-tK8u0qAGF)}h-XJldk0B^7p!2kdN literal 256 zcmYddWMoKYWMoKTWMlw=R7NI-bSN9d&tQ~fXk?TEF|p#=jEoF(7#SJnGBPsEL(&IR zJfD$~VF4o}!$L+zhDBK97c(+3EM;VZDQ8&D$jGn)N!?0DL55w79B_Gb#vw*lhT}-; cPe9ox85tQ)LD|T9PD91cFfuZnWn^Li0MvOBp8x;= diff --git a/core/rexcode/mips/tables/mips.idx_special3.bin b/core/rexcode/mips/tables/mips.idx_special3.bin index 53ed01c63bf3c1690039e6d2bd7c9236250376c3..85961a580edac7cfb6c2adb3756aed941cfce18b 100644 GIT binary patch literal 256 zcmdnT#KdrbiIL$T6C=YRCPs$COpFXim>3z3GBGk7V`5~0f#XcfVCE?#vC~W(440Y2 v7+x~*GyGuUXJBU*1FIp0kY#2?QLem>3y$GchvkVPa%}fxS%3VCDfNv4cz;3@4ey v816IiGrVKsXZXt`23A7~AcKQK)IX>$zM