rexcode/mips: FPU conditional-move + convert-to-FP forms

MOVN/MOVZ.S/.D (FP move on GPR nonzero/zero, enc {FD,FS,RT}), MOVF/MOVT.
S/.D (FP move on FP condition code, enc {FD,FS,FCC_BC}), and the
convert-to-FP forms FCVT_D_W/S_D/S_W (cvt.d.w/cvt.s.d/cvt.s.w). 11 forms.
Spot-checked byte-exact vs llvm-mc and decode-clean; 281 tests green.
This commit is contained in:
Brendan Punsky
2026-06-18 03:27:23 -04:00
committed by Flāvius
parent 5b47f0ca29
commit 930b988ebf
12 changed files with 973 additions and 862 deletions

View File

@@ -504,6 +504,22 @@ inst_rsqrt_s_f_f :: #force_inline proc "contextless" (dst: FPR, src: F
emit_rsqrt_s_f_f :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: FPR, src: FPR) { append(instructions, inst_rsqrt_s_f_f(dst, src)) }
inst_rsqrt_d_f_f :: #force_inline proc "contextless" (dst: FPR, src: FPR) -> Instruction { return Instruction{mnemonic = .RSQRT_D, operand_count = 2, length = 4, ops = {op_fpr(dst), op_fpr(src), {}, {}}} }
emit_rsqrt_d_f_f :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: FPR, src: FPR) { append(instructions, inst_rsqrt_d_f_f(dst, src)) }
inst_movn_s_f_f_r :: #force_inline proc "contextless" (dst: FPR, src: FPR, src2: GPR) -> Instruction { return Instruction{mnemonic = .MOVN_S, operand_count = 3, length = 4, ops = {op_fpr(dst), op_fpr(src), op_gpr(src2), {}}} }
emit_movn_s_f_f_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: FPR, src: FPR, src2: GPR) { append(instructions, inst_movn_s_f_f_r(dst, src, src2)) }
inst_movn_d_f_f_r :: #force_inline proc "contextless" (dst: FPR, src: FPR, src2: GPR) -> Instruction { return Instruction{mnemonic = .MOVN_D, operand_count = 3, length = 4, ops = {op_fpr(dst), op_fpr(src), op_gpr(src2), {}}} }
emit_movn_d_f_f_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: FPR, src: FPR, src2: GPR) { append(instructions, inst_movn_d_f_f_r(dst, src, src2)) }
inst_movz_s_f_f_r :: #force_inline proc "contextless" (dst: FPR, src: FPR, src2: GPR) -> Instruction { return Instruction{mnemonic = .MOVZ_S, operand_count = 3, length = 4, ops = {op_fpr(dst), op_fpr(src), op_gpr(src2), {}}} }
emit_movz_s_f_f_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: FPR, src: FPR, src2: GPR) { append(instructions, inst_movz_s_f_f_r(dst, src, src2)) }
inst_movz_d_f_f_r :: #force_inline proc "contextless" (dst: FPR, src: FPR, src2: GPR) -> Instruction { return Instruction{mnemonic = .MOVZ_D, operand_count = 3, length = 4, ops = {op_fpr(dst), op_fpr(src), op_gpr(src2), {}}} }
emit_movz_d_f_f_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: FPR, src: FPR, src2: GPR) { append(instructions, inst_movz_d_f_f_r(dst, src, src2)) }
inst_movf_s_f_f_cc :: #force_inline proc "contextless" (dst: FPR, src: FPR, imm: i64) -> Instruction { return Instruction{mnemonic = .MOVF_S, operand_count = 3, length = 4, ops = {op_fpr(dst), op_fpr(src), op_imm(imm, 1), {}}} }
emit_movf_s_f_f_cc :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: FPR, src: FPR, imm: i64) { append(instructions, inst_movf_s_f_f_cc(dst, src, imm)) }
inst_movf_d_f_f_cc :: #force_inline proc "contextless" (dst: FPR, src: FPR, imm: i64) -> Instruction { return Instruction{mnemonic = .MOVF_D, operand_count = 3, length = 4, ops = {op_fpr(dst), op_fpr(src), op_imm(imm, 1), {}}} }
emit_movf_d_f_f_cc :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: FPR, src: FPR, imm: i64) { append(instructions, inst_movf_d_f_f_cc(dst, src, imm)) }
inst_movt_s_f_f_cc :: #force_inline proc "contextless" (dst: FPR, src: FPR, imm: i64) -> Instruction { return Instruction{mnemonic = .MOVT_S, operand_count = 3, length = 4, ops = {op_fpr(dst), op_fpr(src), op_imm(imm, 1), {}}} }
emit_movt_s_f_f_cc :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: FPR, src: FPR, imm: i64) { append(instructions, inst_movt_s_f_f_cc(dst, src, imm)) }
inst_movt_d_f_f_cc :: #force_inline proc "contextless" (dst: FPR, src: FPR, imm: i64) -> Instruction { return Instruction{mnemonic = .MOVT_D, operand_count = 3, length = 4, ops = {op_fpr(dst), op_fpr(src), op_imm(imm, 1), {}}} }
emit_movt_d_f_f_cc :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: FPR, src: FPR, imm: i64) { append(instructions, inst_movt_d_f_f_cc(dst, src, imm)) }
inst_cvt_s_d_f_f :: #force_inline proc "contextless" (dst: FPR, src: FPR) -> Instruction { return Instruction{mnemonic = .CVT_S_D, operand_count = 2, length = 4, ops = {op_fpr(dst), op_fpr(src), {}, {}}} }
emit_cvt_s_d_f_f :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: FPR, src: FPR) { append(instructions, inst_cvt_s_d_f_f(dst, src)) }
inst_cvt_s_w_f_f :: #force_inline proc "contextless" (dst: FPR, src: FPR) -> Instruction { return Instruction{mnemonic = .CVT_S_W, operand_count = 2, length = 4, ops = {op_fpr(dst), op_fpr(src), {}, {}}} }
@@ -1466,6 +1482,12 @@ inst_ftrunc_u_w_w_w :: #force_inline proc "contextless" (dst: Register, s
emit_ftrunc_u_w_w_w :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register) { append(instructions, inst_ftrunc_u_w_w_w(dst, src)) }
inst_ftrunc_u_d_w_w :: #force_inline proc "contextless" (dst: Register, src: Register) -> Instruction { return Instruction{mnemonic = .FTRUNC_U_D, operand_count = 2, length = 4, ops = {op_reg(dst), op_reg(src), {}, {}}} }
emit_ftrunc_u_d_w_w :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, src: Register) { append(instructions, inst_ftrunc_u_d_w_w(dst, src)) }
inst_fcvt_s_w_f_f :: #force_inline proc "contextless" (dst: FPR, src: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_S_W, operand_count = 2, length = 4, ops = {op_fpr(dst), op_fpr(src), {}, {}}} }
emit_fcvt_s_w_f_f :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: FPR, src: FPR) { append(instructions, inst_fcvt_s_w_f_f(dst, src)) }
inst_fcvt_s_d_f_f :: #force_inline proc "contextless" (dst: FPR, src: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_S_D, operand_count = 2, length = 4, ops = {op_fpr(dst), op_fpr(src), {}, {}}} }
emit_fcvt_s_d_f_f :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: FPR, src: FPR) { append(instructions, inst_fcvt_s_d_f_f(dst, src)) }
inst_fcvt_d_w_f_f :: #force_inline proc "contextless" (dst: FPR, src: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_D_W, operand_count = 2, length = 4, ops = {op_fpr(dst), op_fpr(src), {}, {}}} }
emit_fcvt_d_w_f_f :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: FPR, src: FPR) { append(instructions, inst_fcvt_d_w_f_f(dst, src)) }
inst_ld_b_w_m :: #force_inline proc "contextless" (dst: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .LD_B, operand_count = 2, length = 4, ops = {op_reg(dst), op_mem(mem, 4), {}, {}}} }
emit_ld_b_w_m :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: Register, mem: Memory) { append(instructions, inst_ld_b_w_m(dst, mem)) }
inst_ld_h_w_m :: #force_inline proc "contextless" (dst: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .LD_H, operand_count = 2, length = 4, ops = {op_reg(dst), op_mem(mem, 4), {}, {}}} }
@@ -2349,6 +2371,22 @@ inst_rsqrt_s :: inst_rsqrt_s_f_f
emit_rsqrt_s :: emit_rsqrt_s_f_f
inst_rsqrt_d :: inst_rsqrt_d_f_f
emit_rsqrt_d :: emit_rsqrt_d_f_f
inst_movn_s :: inst_movn_s_f_f_r
emit_movn_s :: emit_movn_s_f_f_r
inst_movn_d :: inst_movn_d_f_f_r
emit_movn_d :: emit_movn_d_f_f_r
inst_movz_s :: inst_movz_s_f_f_r
emit_movz_s :: emit_movz_s_f_f_r
inst_movz_d :: inst_movz_d_f_f_r
emit_movz_d :: emit_movz_d_f_f_r
inst_movf_s :: inst_movf_s_f_f_cc
emit_movf_s :: emit_movf_s_f_f_cc
inst_movf_d :: inst_movf_d_f_f_cc
emit_movf_d :: emit_movf_d_f_f_cc
inst_movt_s :: inst_movt_s_f_f_cc
emit_movt_s :: emit_movt_s_f_f_cc
inst_movt_d :: inst_movt_d_f_f_cc
emit_movt_d :: emit_movt_d_f_f_cc
inst_cvt_s_d :: inst_cvt_s_d_f_f
emit_cvt_s_d :: emit_cvt_s_d_f_f
inst_cvt_s_w :: inst_cvt_s_w_f_f
@@ -3311,6 +3349,12 @@ inst_ftrunc_u_w :: inst_ftrunc_u_w_w_w
emit_ftrunc_u_w :: emit_ftrunc_u_w_w_w
inst_ftrunc_u_d :: inst_ftrunc_u_d_w_w
emit_ftrunc_u_d :: emit_ftrunc_u_d_w_w
inst_fcvt_s_w :: inst_fcvt_s_w_f_f
emit_fcvt_s_w :: emit_fcvt_s_w_f_f
inst_fcvt_s_d :: inst_fcvt_s_d_f_f
emit_fcvt_s_d :: emit_fcvt_s_d_f_f
inst_fcvt_d_w :: inst_fcvt_d_w_f_f
emit_fcvt_d_w :: emit_fcvt_d_w_f_f
inst_ld_b :: inst_ld_b_w_m
emit_ld_b :: emit_ld_b_w_m
inst_ld_h :: inst_ld_h_w_m

View File

@@ -1589,5 +1589,16 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{
.CMPU_EQ_QB = { {.CMPU_EQ_QB, {.GPR,.GPR,.NONE,.NONE}, {.RS,.RT,.NONE,.NONE}, 0x7C000011, 0xFC00FFFF, .DSP_R2, {}} },
.CMPU_LE_QB = { {.CMPU_LE_QB, {.GPR,.GPR,.NONE,.NONE}, {.RS,.RT,.NONE,.NONE}, 0x7C000091, 0xFC00FFFF, .DSP_R2, {}} },
.CMPU_LT_QB = { {.CMPU_LT_QB, {.GPR,.GPR,.NONE,.NONE}, {.RS,.RT,.NONE,.NONE}, 0x7C000051, 0xFC00FFFF, .DSP_R2, {}} },
.MOVN_S = { {.MOVN_S, {.FPR_S,.FPR_S,.GPR,.NONE}, {.FD,.FS,.RT,.NONE}, 0x46000013, 0xFFE0003F, .FPU, {}} },
.MOVN_D = { {.MOVN_D, {.FPR_D,.FPR_D,.GPR,.NONE}, {.FD,.FS,.RT,.NONE}, 0x46200013, 0xFFE0003F, .FPU, {}} },
.MOVZ_S = { {.MOVZ_S, {.FPR_S,.FPR_S,.GPR,.NONE}, {.FD,.FS,.RT,.NONE}, 0x46000012, 0xFFE0003F, .FPU, {}} },
.MOVZ_D = { {.MOVZ_D, {.FPR_D,.FPR_D,.GPR,.NONE}, {.FD,.FS,.RT,.NONE}, 0x46200012, 0xFFE0003F, .FPU, {}} },
.MOVF_S = { {.MOVF_S, {.FPR_S,.FPR_S,.FCC,.NONE}, {.FD,.FS,.FCC_BC,.NONE}, 0x46000011, 0xFFE3003F, .FPU, {}} },
.MOVF_D = { {.MOVF_D, {.FPR_D,.FPR_D,.FCC,.NONE}, {.FD,.FS,.FCC_BC,.NONE}, 0x46200011, 0xFFE3003F, .FPU, {}} },
.MOVT_S = { {.MOVT_S, {.FPR_S,.FPR_S,.FCC,.NONE}, {.FD,.FS,.FCC_BC,.NONE}, 0x46010011, 0xFFE3003F, .FPU, {}} },
.MOVT_D = { {.MOVT_D, {.FPR_D,.FPR_D,.FCC,.NONE}, {.FD,.FS,.FCC_BC,.NONE}, 0x46210011, 0xFFE3003F, .FPU, {}} },
.FCVT_D_W = { {.FCVT_D_W, {.FPR_D,.FPR_W,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46800021, 0xFFFF003F, .FPU, {}} },
.FCVT_S_D = { {.FCVT_S_D, {.FPR_S,.FPR_D,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46200020, 0xFFFF003F, .FPU, {}} },
.FCVT_S_W = { {.FCVT_S_W, {.FPR_S,.FPR_W,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46800020, 0xFFFF003F, .FPU, {}} },
// SPECGEN:END
}

View File

@@ -8,7 +8,7 @@ package rexcode_mips_generated
import lib "../.."
@(rodata)
DECODE_ENTRIES := [920]lib.Decode_Entry{
DECODE_ENTRIES := [931]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, {} },
@@ -172,6 +172,8 @@ DECODE_ENTRIES := [920]lib.Decode_Entry{
{ .CEIL_L_S, {.FPR_L,.FPR_S,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x4600000A, 0xFFFF003F, .MIPS_III, {only_64=true} },
{ .FLOOR_W_S, {.FPR_W,.FPR_S,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x4600000F, 0xFFFF003F, .MIPS_II, {} },
{ .FLOOR_L_S, {.FPR_L,.FPR_S,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x4600000B, 0xFFFF003F, .MIPS_III, {only_64=true} },
{ .MOVF_S, {.FPR_S,.FPR_S,.FCC,.NONE}, {.FD,.FS,.FCC_BC,.NONE}, 0x46000011, 0xFFE3003F, .FPU, {} },
{ .MOVT_S, {.FPR_S,.FPR_S,.FCC,.NONE}, {.FD,.FS,.FCC_BC,.NONE}, 0x46010011, 0xFFE3003F, .FPU, {} },
{ .C_F_S, {.FPR_S,.FPR_S,.FCC,.NONE}, {.FS,.FT,.FCC_CC,.NONE}, 0x46000030, 0xFFE000FF, .FPU, {} },
{ .C_UN_S, {.FPR_S,.FPR_S,.FCC,.NONE}, {.FS,.FT,.FCC_CC,.NONE}, 0x46000031, 0xFFE000FF, .FPU, {} },
{ .C_EQ_S, {.FPR_S,.FPR_S,.FCC,.NONE}, {.FS,.FT,.FCC_CC,.NONE}, 0x46000032, 0xFFE000FF, .FPU, {} },
@@ -192,6 +194,8 @@ DECODE_ENTRIES := [920]lib.Decode_Entry{
{ .SUB_S, {.FPR_S,.FPR_S,.FPR_S,.NONE}, {.FD,.FS,.FT,.NONE}, 0x46000001, 0xFFE0003F, .FPU, {} },
{ .MUL_S, {.FPR_S,.FPR_S,.FPR_S,.NONE}, {.FD,.FS,.FT,.NONE}, 0x46000002, 0xFFE0003F, .FPU, {} },
{ .DIV_S, {.FPR_S,.FPR_S,.FPR_S,.NONE}, {.FD,.FS,.FT,.NONE}, 0x46000003, 0xFFE0003F, .FPU, {} },
{ .MOVN_S, {.FPR_S,.FPR_S,.GPR,.NONE}, {.FD,.FS,.RT,.NONE}, 0x46000013, 0xFFE0003F, .FPU, {} },
{ .MOVZ_S, {.FPR_S,.FPR_S,.GPR,.NONE}, {.FD,.FS,.RT,.NONE}, 0x46000012, 0xFFE0003F, .FPU, {} },
{ .SQRT_D, {.FPR_D,.FPR_D,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46200004, 0xFFFF003F, .MIPS_II, {} },
{ .ABS_D, {.FPR_D,.FPR_D,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46200005, 0xFFFF003F, .FPU, {} },
{ .NEG_D, {.FPR_D,.FPR_D,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46200007, 0xFFFF003F, .FPU, {} },
@@ -209,6 +213,9 @@ DECODE_ENTRIES := [920]lib.Decode_Entry{
{ .CEIL_L_D, {.FPR_L,.FPR_D,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x4620000A, 0xFFFF003F, .MIPS_III, {only_64=true} },
{ .FLOOR_W_D, {.FPR_W,.FPR_D,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x4620000F, 0xFFFF003F, .MIPS_II, {} },
{ .FLOOR_L_D, {.FPR_L,.FPR_D,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x4620000B, 0xFFFF003F, .MIPS_III, {only_64=true} },
{ .FCVT_S_D, {.FPR_S,.FPR_D,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46200020, 0xFFFF003F, .FPU, {} },
{ .MOVF_D, {.FPR_D,.FPR_D,.FCC,.NONE}, {.FD,.FS,.FCC_BC,.NONE}, 0x46200011, 0xFFE3003F, .FPU, {} },
{ .MOVT_D, {.FPR_D,.FPR_D,.FCC,.NONE}, {.FD,.FS,.FCC_BC,.NONE}, 0x46210011, 0xFFE3003F, .FPU, {} },
{ .C_F_D, {.FPR_D,.FPR_D,.FCC,.NONE}, {.FS,.FT,.FCC_CC,.NONE}, 0x46200030, 0xFFE000FF, .FPU, {} },
{ .C_UN_D, {.FPR_D,.FPR_D,.FCC,.NONE}, {.FS,.FT,.FCC_CC,.NONE}, 0x46200031, 0xFFE000FF, .FPU, {} },
{ .C_EQ_D, {.FPR_D,.FPR_D,.FCC,.NONE}, {.FS,.FT,.FCC_CC,.NONE}, 0x46200032, 0xFFE000FF, .FPU, {} },
@@ -229,8 +236,12 @@ DECODE_ENTRIES := [920]lib.Decode_Entry{
{ .SUB_D, {.FPR_D,.FPR_D,.FPR_D,.NONE}, {.FD,.FS,.FT,.NONE}, 0x46200001, 0xFFE0003F, .FPU, {} },
{ .MUL_D, {.FPR_D,.FPR_D,.FPR_D,.NONE}, {.FD,.FS,.FT,.NONE}, 0x46200002, 0xFFE0003F, .FPU, {} },
{ .DIV_D, {.FPR_D,.FPR_D,.FPR_D,.NONE}, {.FD,.FS,.FT,.NONE}, 0x46200003, 0xFFE0003F, .FPU, {} },
{ .MOVN_D, {.FPR_D,.FPR_D,.GPR,.NONE}, {.FD,.FS,.RT,.NONE}, 0x46200013, 0xFFE0003F, .FPU, {} },
{ .MOVZ_D, {.FPR_D,.FPR_D,.GPR,.NONE}, {.FD,.FS,.RT,.NONE}, 0x46200012, 0xFFE0003F, .FPU, {} },
{ .CVT_S_W, {.FPR_S,.FPR_W,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46800020, 0xFFFF003F, .FPU, {} },
{ .CVT_D_W, {.FPR_D,.FPR_W,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46800021, 0xFFFF003F, .FPU, {} },
{ .FCVT_S_W, {.FPR_S,.FPR_W,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46800020, 0xFFFF003F, .FPU, {} },
{ .FCVT_D_W, {.FPR_D,.FPR_W,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46800021, 0xFFFF003F, .FPU, {} },
{ .CVT_S_L, {.FPR_S,.FPR_L,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46A00020, 0xFFFF003F, .MIPS_III, {only_64=true} },
{ .CVT_D_L, {.FPR_D,.FPR_L,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46A00021, 0xFFFF003F, .MIPS_III, {only_64=true} },
{ .ABS_PS, {.FPR_PS,.FPR_PS,.NONE,.NONE}, {.FD,.FS,.NONE,.NONE}, 0x46C00005, 0xFFFF003F, .MIPS_V, {} },
@@ -950,53 +961,53 @@ DECODE_INDEX_PRIMARY := [64]lib.Decode_Index{
0x0E = { 116, 1},
0x0F = { 117, 2},
0x10 = { 119, 13},
0x11 = { 132, 114},
0x12 = { 246, 36},
0x13 = { 282, 5},
0x14 = { 287, 1},
0x15 = { 288, 1},
0x16 = { 289, 1},
0x17 = { 290, 1},
0x18 = { 291, 13},
0x19 = { 304, 15},
0x1A = { 319, 1},
0x1B = { 320, 13},
0x1C = { 333, 109},
0x1D = { 442, 1},
0x1E = { 443, 220},
0x1F = { 663, 112},
0x20 = { 775, 1},
0x21 = { 776, 1},
0x22 = { 777, 1},
0x23 = { 778, 1},
0x24 = { 779, 1},
0x25 = { 780, 1},
0x26 = { 781, 1},
0x27 = { 782, 1},
0x28 = { 783, 1},
0x29 = { 784, 1},
0x2A = { 785, 1},
0x2B = { 786, 1},
0x2C = { 787, 1},
0x2D = { 788, 1},
0x2E = { 789, 1},
0x2F = { 790, 1},
0x30 = { 791, 1},
0x31 = { 792, 1},
0x32 = { 793, 3},
0x33 = { 796, 1},
0x34 = { 797, 63},
0x35 = { 860, 3},
0x36 = { 863, 5},
0x37 = { 868, 6},
0x38 = { 874, 1},
0x39 = { 875, 1},
0x3A = { 876, 3},
0x3B = { 879, 2},
0x3C = { 881, 27},
0x3D = { 908, 3},
0x3E = { 911, 5},
0x3F = { 916, 4},
0x11 = { 132, 125},
0x12 = { 257, 36},
0x13 = { 293, 5},
0x14 = { 298, 1},
0x15 = { 299, 1},
0x16 = { 300, 1},
0x17 = { 301, 1},
0x18 = { 302, 13},
0x19 = { 315, 15},
0x1A = { 330, 1},
0x1B = { 331, 13},
0x1C = { 344, 109},
0x1D = { 453, 1},
0x1E = { 454, 220},
0x1F = { 674, 112},
0x20 = { 786, 1},
0x21 = { 787, 1},
0x22 = { 788, 1},
0x23 = { 789, 1},
0x24 = { 790, 1},
0x25 = { 791, 1},
0x26 = { 792, 1},
0x27 = { 793, 1},
0x28 = { 794, 1},
0x29 = { 795, 1},
0x2A = { 796, 1},
0x2B = { 797, 1},
0x2C = { 798, 1},
0x2D = { 799, 1},
0x2E = { 800, 1},
0x2F = { 801, 1},
0x30 = { 802, 1},
0x31 = { 803, 1},
0x32 = { 804, 3},
0x33 = { 807, 1},
0x34 = { 808, 63},
0x35 = { 871, 3},
0x36 = { 874, 5},
0x37 = { 879, 6},
0x38 = { 885, 1},
0x39 = { 886, 1},
0x3A = { 887, 3},
0x3B = { 890, 2},
0x3C = { 892, 27},
0x3D = { 919, 3},
0x3E = { 922, 5},
0x3F = { 927, 4},
}
@(rodata)
@@ -1101,66 +1112,66 @@ DECODE_INDEX_COP1 := [32]lib.Decode_Index{
0x08 = { 140, 4},
0x09 = { 144, 1},
0x0D = { 145, 1},
0x10 = { 146, 37},
0x11 = { 183, 37},
0x14 = { 220, 2},
0x15 = { 222, 2},
0x16 = { 224, 22},
0x10 = { 146, 41},
0x11 = { 187, 42},
0x14 = { 229, 4},
0x15 = { 233, 2},
0x16 = { 235, 22},
}
@(rodata)
DECODE_INDEX_SPECIAL2 := [64]lib.Decode_Index{
0x00 = { 333, 1},
0x01 = { 334, 1},
0x02 = { 335, 1},
0x04 = { 336, 2},
0x05 = { 338, 1},
0x08 = { 339, 25},
0x09 = { 364, 26},
0x10 = { 390, 1},
0x11 = { 391, 1},
0x12 = { 392, 1},
0x13 = { 393, 1},
0x18 = { 394, 1},
0x19 = { 395, 1},
0x1A = { 396, 1},
0x1B = { 397, 1},
0x20 = { 398, 2},
0x21 = { 400, 2},
0x24 = { 402, 1},
0x25 = { 403, 1},
0x28 = { 404, 17},
0x29 = { 421, 8},
0x30 = { 429, 5},
0x31 = { 434, 1},
0x34 = { 435, 1},
0x36 = { 436, 1},
0x37 = { 437, 1},
0x3C = { 438, 1},
0x3E = { 439, 1},
0x3F = { 440, 2},
0x00 = { 344, 1},
0x01 = { 345, 1},
0x02 = { 346, 1},
0x04 = { 347, 2},
0x05 = { 349, 1},
0x08 = { 350, 25},
0x09 = { 375, 26},
0x10 = { 401, 1},
0x11 = { 402, 1},
0x12 = { 403, 1},
0x13 = { 404, 1},
0x18 = { 405, 1},
0x19 = { 406, 1},
0x1A = { 407, 1},
0x1B = { 408, 1},
0x20 = { 409, 2},
0x21 = { 411, 2},
0x24 = { 413, 1},
0x25 = { 414, 1},
0x28 = { 415, 17},
0x29 = { 432, 8},
0x30 = { 440, 5},
0x31 = { 445, 1},
0x34 = { 446, 1},
0x36 = { 447, 1},
0x37 = { 448, 1},
0x3C = { 449, 1},
0x3E = { 450, 1},
0x3F = { 451, 2},
}
@(rodata)
DECODE_INDEX_SPECIAL3 := [64]lib.Decode_Index{
0x00 = { 663, 2},
0x01 = { 665, 1},
0x02 = { 666, 1},
0x03 = { 667, 1},
0x04 = { 668, 1},
0x05 = { 669, 1},
0x06 = { 670, 1},
0x07 = { 671, 1},
0x0A = { 672, 3},
0x0C = { 675, 1},
0x0F = { 676, 8},
0x10 = { 684, 22},
0x11 = { 706, 15},
0x12 = { 721, 9},
0x13 = { 730, 18},
0x20 = { 748, 5},
0x24 = { 753, 4},
0x30 = { 757, 9},
0x38 = { 766, 9},
0x00 = { 674, 2},
0x01 = { 676, 1},
0x02 = { 677, 1},
0x03 = { 678, 1},
0x04 = { 679, 1},
0x05 = { 680, 1},
0x06 = { 681, 1},
0x07 = { 682, 1},
0x0A = { 683, 3},
0x0C = { 686, 1},
0x0F = { 687, 8},
0x10 = { 695, 22},
0x11 = { 717, 15},
0x12 = { 732, 9},
0x13 = { 741, 18},
0x20 = { 759, 5},
0x24 = { 764, 4},
0x30 = { 768, 9},
0x38 = { 777, 9},
}

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,7 @@
-- Run: luajit tablegen/specgen.lua (from mips/, or with a full path)
local bit = require("bit")
local LLVM = "llvm-mc --assemble --triple=mips --mattr=+msa,+dsp,+dspr2 --show-encoding"
local LLVM = "llvm-mc --assemble --triple=mips --mattr=+msa,+dsp,+dspr2,+mips32r2,+fp64 --show-encoding"
local DIR = (arg[0]:match("^(.*)/[^/]*$")) or "."
local TABLE = DIR .. "/encoding_table.odin"
@@ -196,6 +196,29 @@ for _, b in ipairs({
if r then sections[#sections+1]=r end
end
-- ---- FPU conditional move (S/D) -------------------------------------------
for _, b in ipairs({{"MOVN","movn"},{"MOVZ","movz"}}) do
for _, f in ipairs({{"S","s","FPR_S"},{"D","d","FPR_D"}}) do
local r = entry(b[1].."_"..f[1], "{."..f[3]..",."..f[3]..",.GPR,.NONE}", "{.FD,.FS,.RT,.NONE}", "FPU",
function(v) return string.format("%s.%s $f%d,$f%d,$%d", b[2], f[2], v[1], v[2], v[3]) end, {31,31,31})
if r then sections[#sections+1]=r end
end
end
for _, b in ipairs({{"MOVF","movf"},{"MOVT","movt"}}) do
for _, f in ipairs({{"S","s","FPR_S"},{"D","d","FPR_D"}}) do
local r = entry(b[1].."_"..f[1], "{."..f[3]..",."..f[3]..",.FCC,.NONE}", "{.FD,.FS,.FCC_BC,.NONE}", "FPU",
function(v) return string.format("%s.%s $f%d,$f%d,$fcc%d", b[2], f[2], v[1], v[2], v[3]) end, {31,31,7})
if r then sections[#sections+1]=r end
end
end
-- ---- FPU convert to FP (FCVT_x_y = cvt.x.y) --------------------------------
for _, b in ipairs({{"FCVT_D_W","cvt.d.w","FPR_D","FPR_W"},{"FCVT_S_D","cvt.s.d","FPR_S","FPR_D"},{"FCVT_S_W","cvt.s.w","FPR_S","FPR_W"}}) do
local r = entry(b[1], "{."..b[3]..",."..b[4]..",.NONE,.NONE}", "{.FD,.FS,.NONE,.NONE}", "FPU",
function(v) return string.format("%s $f%d,$f%d", b[2], v[1], v[2]) end, {31,31})
if r then sections[#sections+1]=r end
end
-- ---- splice into the SoT ---------------------------------------------------
local region = " // SPECGEN:BEGIN\n" .. table.concat(sections, "\n") .. "\n // SPECGEN:END"
local fh = assert(io.open(TABLE, "r")); local src = fh:read("*a"); fh:close()