diff --git a/src/jit/dis_loongarch64.lua b/src/jit/dis_loongarch64.lua index 96a2b322f..a334445e3 100644 --- a/src/jit/dis_loongarch64.lua +++ b/src/jit/dis_loongarch64.lua @@ -23,8 +23,8 @@ local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift -- Opcode maps ------------------------------------------------------------------------------ -local map_18_0 = { -- 18-20:0, 10-17 - shift = 10, mask = 255, +local map_zero_31_15 = { -- [31:15] = 0 + shift = 10, mask = 0xff, [4] = "clo.wDJ", [5] = "clz.wDJ", [6] = "cto.wDJ", @@ -47,189 +47,57 @@ local map_18_0 = { -- 18-20:0, 10-17 [23] = "ext.w.bDJ", } -local map_18_4 = { -- 18-20:4, 15-17 - shift = 15, mask = 7, - [0] = "add.wDJK", - [1] = "add.dDJK", - [2] = "sub.wDJK", - [3] = "sub.dDJK", - [4] = "sltDJK", - [5] = "sltuDJK", - [6] = "maskeqzDJK", - [7] = "masknezDJK", -} - -local map_18_5 = { -- 18-20:5, 15-17 - shift = 15, mask = 7, - [0] = "norDJK", - [1] = "andDJK", - [2] = "orDJK", - [3] = "xorDJK", - [4] = "ornDJK", - [5] = "andnDJK", - [6] = "sll.wDJK", - [7] = "srl.wDJK", -} - -local map_18_6 = { -- 18-20:6, 15-17 - shift = 15, mask = 7, - [0] = "sra.wDJK", - [1] = "sll.dDJK", - [2] = "srl.dDJK", - [3] = "sra.dDJK", - [6] = "rotr.wDJK", - [7] = "rotr.dDJK", -} - -local map_18_7 = { -- 18-20:7, 15-17 - shift = 15, mask = 7, - [0] = "mul.wDJK", - [1] = "mulh.wDJK", - [2] = "mulh.wuDJK", - [3] = "mul.dDJK", - [4] = "mulh.dDJK", - [5] = "mulh.duDJK", - [6] = "mulw.d.wDJK", - [7] = "mulw.d.wuDJK", -} - -local map_farith2 = { - shift = 10, mask = 31, - [1] = "fabs.sFG", - [2] = "fabs.dFG", - [5] = "fneg.sFG", - [6] = "fneg.dFG", - [9] = "flogb.sFG", - [10] = "flogb.dFG", - [13] = "fclass.sFG", - [14] = "fclass.dFG", - [17] = "fsqrt.sFG", - [18] = "fsqrt.dFG", - [21] = "frecip.sFG", - [22] = "frecip.dFG", - [25] = "frsqrt.sFG", - [26] = "frsqrt.dFG", - [29] = "frecipe.sFG", - [30] = "frecipe.dFG", - [33] = "frsqrte.sFG", - [34] = "frsqrte.dFG", -} - -local map_fmov = { - shift = 10, mask = 31, - [5] = "fmov.sFG", - [6] = "fmov.dFG", - [9] = "movgr2fr.wFJ", - [10] = "movgr2fr.dFJ", - [11] = "movgr2frh.wFJ", - [13] = "movfr2gr.sDG", - [14] = "movfr2gr.dDG", - [15] = "movfrh2gr.sDG", - [16] = "movgr2fcsrSJ", - [18] = "movfcsr2grDR", - [20] = { shift = 3, mask = 3, [0] = "movfr2cfEG", }, - [21] = { shift = 8, mask = 3, [0] = "movcf2frFA", }, - [22] = { shift = 3, mask = 3, [0] = "movgr2cfEJ", }, - [23] = { shift = 8, mask = 3, [0] = "movcf2grDA", }, -} - -local map_fconvert = { -- 15-20: 110010 - shift = 10, mask = 31, - [6] = "fcvt.s.dFG", [9] = "fcvt.d.sFG", -} - -local map_fconvert1 = { -- 15-20: 110100 - shift = 10, mask = 31, - [1] = "ftintrm.w.sFG", - [2] = "ftintrm.w.dFG", - [9] = "ftintrm.l.sFG", - [10] = "ftintrm.l.dFG", - [17] = "ftintrp.w.sFG", - [18] = "ftintrp.w.dFG", - [25] = "ftintrp.l.sFG", - [26] = "ftintrp.l.dFG", -} - -local map_fconvert2 = { -- 15-20: 110101 - shift = 10, mask = 31, - [1] = "ftintrz.w.sFG", - [2] = "ftintrz.w.dFG", - [9] = "ftintrz.l.sFG", - [10] = "ftintrz.l.dFG", - [17] = "ftintrne.w.sFG", - [18] = "ftintrne.w.dFG", - [25] = "ftintrne.l.sFG", - [26] = "ftintrne.l.dFG", -} - -local map_fconvert3 = { -- 15-20: 110110 - shift = 10, mask = 31, - [1] = "ftint.w.sFG", - [2] = "ftint.w.dFG", - [9] = "ftint.l.sFG", - [10] = "ftint.l.dFG", -} - -local map_fconvert4 = { -- 15-20: 111010 - shift = 10, mask = 31, - [4] = "ffint.s.wFG", - [6] = "ffint.s.lFG", - [8] = "ffint.d.wFG", - [10] = "ffint.d.lFG", -} - -local map_fconvert5 = { -- 15-20: 111100 - shift = 10, mask = 31, - [17] = "frint.sFG", - [18] = "frint.dFG", -} - -local map_farith = { -- 22-25:4, 15-21 - shift = 15, mask = 127, - [1] = "fadd.sFGH", - [2] = "fadd.dFGH", - [5] = "fsub.sFGH", - [6] = "fsub.dFGH", - [9] = "fmul.sFGH", - [10] = "fmul.dFGH", - [13] = "fdiv.sFGH", - [14] = "fdiv.dFGH", - [17] = "fmax.sFGH", - [18] = "fmax.dFGH", - [21] = "fmin.sFGH", - [22] = "fmin.dFGH", - [25] = "fmaxa.sFGH", - [26] = "fmaxa.dFGH", - [29] = "fmina.sFGH", - [30] = "fmina.dFGH", - [33] = "fscaleb.sFGH", - [34] = "fscaleb.dFGH", - [37] = "fcopysign.sFGH", - [38] = "fcopysign.dFGH", - [40] = map_farith2, [41] = map_fmov, - [50] = map_fconvert, [52] = map_fconvert1, - [53] = map_fconvert2, [54] = map_fconvert3, - [58] = map_fconvert4, [60] = map_fconvert5, -} - -local map_21_0 = { --21st:0, 18-20 - shift = 18, mask = 7, - [0] = map_18_0, - [1] = { shift = 17, mask = 1, [0] = "alsl.wDJKQ", "alsl.wuDJKQ", }, - [2] = {shift = 17, mask = 1, [0] = "bytepick.wDJKQ", }, +local map_zero_31_20 = { -- [31:20] = 0 + shift = 18, mask = 0x3, + [0] = map_zero_31_15, + [1] = { + shift = 17, mask = 0x1, + [0] = "alsl.wDJKQ", "alsl.wuDJKQ", + }, + [2] = "bytepick.wDJKQ", [3] = "bytepick.dDJKB", - [4] = map_18_4, - [5] = map_18_5, - [6] = map_18_6, - [7] = map_18_7, } -local map_21_1 = { --21st:1, 22nd:0, 15-20 - shift = 21, mask = 1, +local map_zero_31_22 = { -- [31:22] = 0 + shift = 20, mask = 0x3, + [0] = map_zero_31_20, [1] = { - shift = 18, mask = 7, + shift = 15, mask = 0x1f, + [0] = "add.wDJK", + [1] = "add.dDJK", + [2] = "sub.wDJK", + [3] = "sub.dDJK", + [4] = "sltDJK", + [5] = "sltuDJK", + [6] = "maskeqzDJK", + [7] = "masknezDJK", + [8] = "norDJK", + [9] = "andDJK", + [10] = "orDJK", + [11] = "xorDJK", + [12] = "ornDJK", + [13] = "andnDJK", + [14] = "sll.wDJK", + [15] = "srl.wDJK", + [16] = "sra.wDJK", + [17] = "sll.dDJK", + [18] = "srl.dDJK", + [19] = "sra.dDJK", + [22] = "rotr.wDJK", + [23] = "rotr.dDJK", + [24] = "mul.wDJK", + [25] = "mulh.wDJK", + [26] = "mulh.wuDJK", + [27] = "mul.dDJK", + [28] = "mulh.dDJK", + [29] = "mulh.duDJK", + [30] = "mulw.d.wDJK", + [31] = "mulw.d.wuDJK", + }, + [2] = { + shift = 19, mask = 0x1, [0] = { - shift = 15, mask = 7, + shift = 15, mask = 0x1f, [0] = "div.wDJK", [1] = "mod.wDJK", [2] = "div.wuDJK", @@ -240,230 +108,382 @@ local map_21_1 = { --21st:1, 22nd:0, 15-20 [7] = "mod.duDJK", }, [1] = { - shift = 18, mask = 7, - [0] = "crc.w.b.wDJK", - [1] = "crc.w.h.wDJK", - [2] = "crc.w.w.wDJK", - [3] = "crc.w.d.wDJK", - [4] = "crcc.w.b.wDJK", - [5] = "crcc.w.h.wDJK", - [6] = "crcc.w.w.wDJK", - [7] = "crcc.w.d.wDJK", - }, - [2] = { - shift = 15, mask = 7, - [4] = breakC, [6] = syscallC, + shift = 17, mask = 0x7, + [6] = "alsl.dDJKQ", }, - [3] = { shift = 17, mask = 1, [0] = "alsl.dDJKQ", }, }, } -local map_22_0 = { - shift = 21, mask = 1, - [0] = map_21_0, - [1] = map_21_1, -} - -local map_shift = { -- 22nd:1, 21st:0 - shift = 16, mask = 31, - [0] = { shift = 15, mask = 1, [1] = "slli.wDJU", }, - [1] = "slli.dDJV", - [4] = { shift = 15, mask = 1, [1] = "srli.wDJU", }, - [5] = "srli.dDJV", - [8] = { shift = 15, mask = 1, [1] = "srai.wDJU", }, - [9] = "srai.dDJV", - [12] = { shift = 15, mask = 1, [1] = "rotri.wDJU", }, - [13] = "rotri.dDJV", -} - -local map_22_1 = { -- 22nd:1 - shift = 21, mask = 1, - [0] = map_shift, - [1] = { shift = 15, mask = 1, [0] = "bstrins.wDJMU", [1] = "bstrpick.wDJMU", }, -} - -local map_26_0 = { - shift = 22, mask = 15, - [0] = map_22_0, - [1] = map_22_1, +local map_zero_31_23 = { -- [31:24] = 0 + shift = 22, mask = 0x3, + [0] = map_zero_31_22, + [1] = { + shift = 21, mask = 0x1, + [0] = { + shift = 16, mask = 0x1, + [0] = { + shift = 15, mask = 0x1f, + [1] = "slli.wDJU", + [9] = "srli.wDJU", + [17] = "srai.wDJU", + [25] = "rotri.wDJU", + }, + [1] = { + shift = 16, mask = 0xf, + [1] = "slli.dDJV", + [5] = "srli.dDJV", + [9] = "srai.dDJV", + [13] = "rotri.dDJV", + }, + }, + [1] = { + shift = 15, mask = 0x1, + [0] = "bstrins.wDJMU", + [1] = "bstrpick.wDJMU", + }, + }, [2] = "bstrins.dDJNV", [3] = "bstrpick.dDJNV", - [4] = map_farith, - [8] = "sltiDJX", - [9] = "sltuiDJX", - [10] = "addi.wDJX", - [11] = "addi.dDJX", - [12] = "lu52i.dDJX", - [13] = "andiDJT", - [14] = "oriDJT", - [15] = "xoriDJT", -} - -local map_long_i_5 = { -- Long immediate fixed-point arithmetic. - shift = 25, mask = 1, - [0] = "lu12i.wDZ", - [1] = "lu32i.dDZ", } -local map_long_i_6 = { - shift = 25, mask = 1, - [0] = "pcaddiDZ", - [1] = "pcalau12iDZ", -} - -local map_long_i_7 = { - shift = 25, mask = 1, - [0] = "pcaddu12iDZ", - [1] = "pcaddu18iDZ", -} - -local map_ldst0_14 = { - shift = 15, mask = 2047, - [0] = "ldx.bDJK", [8] = "ldx.hDJK", [16] = "ldx.wDJK", - [24] = "ldx.dDJK", [32] = "stx.bDJK", [40] = "stx.hDJK", - [48] = "stx.wDJK", [56] = "stx.dDJK", [64] = "ldx.buDJK", - [72] = "ldx.huDJK", [80] = "ldx.wuDJK", [96] = "fldx.sFJK", - [104] = "fldx.dFJK", [112] = "fstx.sFJK", [120] = "fstx.dFJK", - [232] = "fldgt.sFJK", [233] = "fldgt.dFJK", [234] = "fldle.sFJK", - [235] = "fldle.dFJK", [236] = "fstgt.sFJK", [237] = "fstgt.dFJK", - [238] = "fstle.sFJK", [239] = "fstle.dFJK", [240] = "ldgt.bDJK", - [241] = "ldgt.hDJK", [242] = "ldgt.wDJK", [243] = "ldgt.dDJK", - [244] = "ldle.bDJK", [245] = "ldle.hDJK", [246] = "ldle.wDJK", - [247] = "ldle.dDJK", [248] = "stgt.bDJK", [249] = "stgt.hDJK", - [250] = "stgt.wDJK", [251] = "stgt.dDJK", [252] = "stle.bDJK", - [253] = "stle.hDJK", [254] = "stle.wDJK", [255] = "stle.dDJK", -} - -local map_ldst1_8 = { - shift = 24, mask = 3, - [0] = "ll.wDJW", - [1] = "sc.wDJW", - [2] = "ll.dDJW", - [3] = "sc.dDJW", -} - -local map_ldst1_9 = { - shift = 24, mask = 3, - [0] = "ldptr.wDJW", - [1] = "stptr.wDJW", - [2] = "ldptr.dDJW", - [3] = "stptr.dDJW", -} -local map_ldst1_10 = { - shift = 22, mask = 15, - [0] = "ld.bDJX", - [1] = "ld.hDJX", - [2] = "ld.wDJX", - [3] = "ld.dDJX", - [4] = "st.bDJX", - [5] = "st.hDJX", - [6] = "st.wDJX", - [7] = "st.dDJX", - [8] = "ld.buDJX", - [9] = "ld.huDJX", - [10] = "ld.wuDJX", - [12] = "fld.sFJX", - [13] = "fst.sFJX", - [14] = "fld.dFJX", - [15] = "fst.dFJX", +local map_zero_31_25 = { -- [31:25] = 0 + shift = 24, mask = 0x1, + [0] = map_zero_31_23, + [1] = { + shift = 18, mask = 0x3f, + [0] = { + shift = 15, mask = 0x7, + [1] = "fadd.sFGH", + [2] = "fadd.dFGH", + [5] = "fsub.sFGH", + [6] = "fsub.dFGH", + }, + [1] = { + shift = 15, mask = 0x7, + [1] = "fmul.sFGH", + [2] = "fmul.dFGH", + [5] = "fdiv.sFGH", + [6] = "fdiv.dFGH", + }, + [2] = { + shift = 15, mask = 0x7, + [1] = "fmax.sFGH", + [2] = "fmax.dFGH", + [5] = "fmin.sFGH", + [6] = "fmin.dFGH", + }, + [3] = { + shift = 15, mask = 0x7, + [1] = "fmaxa.sFGH", + [2] = "fmaxa.dFGH", + [5] = "fmina.sFGH", + [6] = "fmina.dFGH", + }, + [4] = { + shift = 15, mask = 0x7, + [1] = "fscaleb.sFGH", + [2] = "fscaleb.dFGH", + [5] = "fcopysign.sFGH", + [6] = "fcopysign.dFGH", + }, + [5] = { + shift = 10, mask = 0xff, + [1] = "fabs.sFG", + [2] = "fabs.dFG", + [5] = "fneg.sFG", + [6] = "fneg.dFG", + [9] = "flogb.sFG", + [10] = "flogb.dFG", + [13] = "fclass.sFG", + [14] = "fclass.dFG", + [17] = "fsqrt.sFG", + [18] = "fsqrt.dFG", + [21] = "frecip.sFG", + [22] = "frecip.dFG", + [25] = "frsqrt.sFG", + [26] = "frsqrt.dFG", + [29] = "frecipe.sFG", + [30] = "frecipe.dFG", + [33] = "frsqrte.sFG", + [34] = "frsqrte.dFG", + + [37] = "fmov.sFG", + [38] = "fmov.dFG", + [41] = "movgr2fr.wFJ", + [42] = "movgr2fr.dFJ", + [43] = "movgr2frh.wFJ", + [45] = "movfr2gr.sDG", + [46] = "movfr2gr.dDG", + [47] = "movfrh2gr.sDG", + [48] = "movgr2fcsrSJ", + [50] = "movfcsr2grDR", + [52] = { shift = 3, mask = 0x3, [0] = "movfr2cfEG", }, + [53] = { shift = 8, mask = 0x3, [0] = "movcf2frFA", }, + [54] = { shift = 3, mask = 0x3, [0] = "movgr2cfEJ", }, + [55] = { shift = 8, mask = 0x3, [0] = "movcf2grDA", }, + }, + [6] = { + shift = 10, mask = 0xff, + [70] = "fcvt.s.dFG", + [73] = "fcvt.d.sFG", + [129] = "ftintrm.w.sFG", + [130] = "ftintrm.w.dFG", + [137] = "ftintrm.l.sFG", + [138] = "ftintrm.l.dFG", + [145] = "ftintrp.w.sFG", + [146] = "ftintrp.w.dFG", + [153] = "ftintrp.l.sFG", + [154] = "ftintrp.l.dFG", + [161] = "ftintrz.w.sFG", + [162] = "ftintrz.w.dFG", + [169] = "ftintrz.l.sFG", + [170] = "ftintrz.l.dFG", + [177] = "ftintrne.w.sFG", + [178] = "ftintrne.w.dFG", + [185] = "ftintrne.l.sFG", + [186] = "ftintrne.l.dFG", + [193] = "ftint.w.sFG", + [194] = "ftint.w.dFG", + [201] = "ftint.l.sFG", + [202] = "ftint.l.dFG", + }, + [7] = { + shift = 10, mask = 0xff, + [68] = "ffint.s.wFG", + [70] = "ffint.s.lFG", + [72] = "ffint.d.wFG", + [74] = "ffint.d.lFG", + [145] = "frint.sFG", + [148] = "frint.dFG", + }, + }, } -local map_fcmp0 = { - shift = 15, mask = 31, - [0] = "fcmp.caf.sEGH", - [1] = "fcmp.saf.sEGH", - [2] = "fcmp.clt.sEGH", - [3] = "fcmp.slt.sEGH", - [4] = "fcmp.ceq.sEGH", - [5] = "fcmp.seq.sEGH", - [6] = "fcmp.cle.sEGH", - [7] = "fcmp.sle.sEGH", - [8] = "fcmp.cun.sEGH", - [9] = "fcmp.sun.sEGH", - [10] = "fcmp.cult.sEGH", - [11] ="fcmp.sult.sEGH", - [12] = "fcmp.cueq.sEGH", - [13] = "fcmp.sueq.sEGH", - [14] = "fcmp.cule.sEGH", - [15] = "fcmp.sule.sEGH", - [16] = "fcmp.cne.sEGH", - [17] = "fcmp.sne.sEGH", - [20] = "fcmp.cor.sEGH", - [21] = "fcmp.sor.sEGH", - [24] = "fcmp.cune.sEGH", - [25] = "fcmp.sune.sEGH", +local map_zero_31_26 = { -- [31:26] = 0 + shift = 25, mask = 0x1, + [0] = map_zero_31_25, + [1] = { + shift = 22, mask = 0x7, + [0] = "sltiDJX", + [1] = "sltuiDJX", + [2] = "addi.wDJX", + [3] = "addi.dDJX", + [4] = "lu52i.dDJX", + [5] = "andiDJT", + [6] = "oriDJT", + [7] = "xoriDJT", + }, } -local map_fcmp1 = { - shift = 15, mask = 31, - [0] = "fcmp.caf.dEGH", - [1] = "fcmp.saf.dEGH", - [2] = "fcmp.clt.dEGH", - [3] = "fcmp.slt.dEGH", - [4] = "fcmp.ceq.dEGH", - [5] = "fcmp.seq.dEGH", - [6] = "fcmp.cle.dEGH", - [7] = "fcmp.sle.dEGH", - [8] = "fcmp.cun.dEGH", - [9] = "fcmp.sun.dEGH", - [10] = "fcmp.cult.dEGH", - [11] = "fcmp.sult.dEGH", - [12] = "fcmp.cueq.dEGH", - [13] = "fcmp.sueq.dEGH", - [14] = "fcmp.cule.dEGH", - [15] = "fcmp.sule.dEGH", - [16] = "fcmp.cne.dEGH", - [17] = "fcmp.sne.dEGH", - [20] = "fcmp.cor.dEGH", - [21] = "fcmp.sor.dEGH", - [24] = "fcmp.cune.dEGH", - [25] = "fcmp.sune.dEGH", +local map_zero_31_28 = { -- [31:28] = 0 + shift = 26, mask = 0x3, + [0] = map_zero_31_26, + [2] = { + shift = 20, mask = 0x3f, + [1] = "fmadd.sFGHi", + [2] = "fmadd.dFGHi", + [5] = "fmsub.sFGHi", + [6] = "fmsub.dFGHi", + [9] = "fnmadd.sFGHi", + [10] = "fnmadd.dFGHi", + [13] = "fnmsub.sFGHi", + [14] = "fnmsub.dFGHi", + }, + [3] = { + shift = 20, mask = 0x7, + [1] = { + shift = 15, mask = 0x1f, + [0] = "fcmp.caf.EGH", + [1] = "fcmp.saf.EGH", + [2] = "fcmp.clt.EGH", + [3] = "fcmp.slt.EGH", + [4] = "fcmp.ceq.EGH", + [5] = "fcmp.seq.EGH", + [6] = "fcmp.cle.EGH", + [7] = "fcmp.sle.EGH", + [8] = "fcmp.cun.EGH", + [9] = "fcmp.sun.EGH", + [10] = "fcmp.cult.EGH", + [11] = "fcmp.sult.EGH", + [12] = "fcmp.cueq.EGH", + [13] = "fcmp.sueq.EGH", + [14] = "fcmp.cule.EGH", + [15] = "fcmp.sule.EGH", + [16] = "fcmp.cne.EGH", + [17] = "fcmp.sne.EGH", + [20] = "fcmp.cor.EGH", + [21] = "fcmp.sor.EGH", + [24] = "fcmp.cune.EGH", + [25] = "fcmp.sune.EGH", + }, + [2] = { + shift = 15, mask = 0x1f, + [0] = "fcmp.caf.EGH", + [1] = "fcmp.saf.EGH", + [2] = "fcmp.clt.EGH", + [3] = "fcmp.slt.EGH", + [4] = "fcmp.ceq.EGH", + [5] = "fcmp.seq.EGH", + [6] = "fcmp.cle.EGH", + [7] = "fcmp.sle.EGH", + [8] = "fcmp.cun.EGH", + [9] = "fcmp.sun.EGH", + [10] = "fcmp.cult.EGH", + [11] = "fcmp.sult.EGH", + [12] = "fcmp.cueq.EGH", + [13] = "fcmp.sueq.EGH", + [14] = "fcmp.cule.EGH", + [15] = "fcmp.sule.EGH", + [16] = "fcmp.cne.EGH", + [17] = "fcmp.sne.EGH", + [20] = "fcmp.cor.EGH", + [21] = "fcmp.sor.EGH", + [24] = "fcmp.cune.EGH", + [25] = "fcmp.sune.EGH", + }, + [16] = { + shift = 18, mask = 0x3, + [0] = "fselFGHI", + }, + }, } -local map_fcmp = { - shift = 20, mask = 63, - [1] = { shift = 3, mask = 3, [0] = map_fcmp0, }, - [2] = { shift = 3, mask = 3, [0] = map_fcmp1, }, - [16] = { shift = 18, mask = 3, [0] = "fselFGHI", }, +local map_zero_31_29 = { -- [31:29] = 0 + shift = 28, mask = 0x1, + [0] = map_zero_31_28, + [1] = { + shift = 26, mask = 0x3, + [0] = "addu16i.dDJY", + [1] = { + shift = 25, mask = 0x1, + [0] = "lu12i.wDZ", + [1] = "lu32i.dDZ", + }, + [2] = { + shift = 25, mask = 0x1, + [0] = "pcaddiDZ", + [1] = "pcalau12iDZ", + }, + [3] = { + shift = 25, mask = 0x1, + [0] = "pcaddu12iDZ", + [1] = "pcaddu18iDZ", + }, + }, } -local map_fp = { - shift = 20, mask = 15, - [1] = "fmadd.sFGHi", - [2] = "fmadd.dFGHi", - [4] = "fmsub.sFGHi", - [5] = "fmsub.dFGHi", - [10] = "fnmadd.dFGHi", - [14] = "fnmsub.dFGHi", +local map_zero_31_31 = { -- [31:31] = 0 + shift = 29, mask = 0x3, + [0] = map_zero_31_29, + [1] = { + shift = 27, mask = 0x3, + [0] = { + shift = 24, mask = 0x7, + [0] = "ll.wDJW", + [1] = "sc.wDJW", + [2] = "ll.dDJW", + [3] = "sc.dDJW", + [4] = "ldptr.wDJW", + [5] = "stptr.wDJW", + [6] = "ldptr.dDJW", + [7] = "stptr.dDJW", + }, + [1] = { + shift = 22, mask = 0x1f, + [0] = "ld.bDJX", + [1] = "ld.hDJX", + [2] = "ld.wDJX", + [3] = "ld.dDJX", + [4] = "st.bDJX", + [5] = "st.hDJX", + [6] = "st.wDJX", + [7] = "st.dDJX", + [8] = "ld.buDJX", + [9] = "ld.huDJX", + [10] = "ld.wuDJX", + [12] = "fld.sFJX", + [13] = "fst.sFJX", + [14] = "fld.dFJX", + [15] = "fst.dFJX", + }, + [3] = { + shift = 21, mask = 0x3f, + [0] = { + shift = 15, mask = 0x3f, + [0] = "ldx.bDJK", + [8] = "ldx.hDJK", + [16] = "ldx.wDJK", + [24] = "ldx.dDJK", + [32] = "stx.bDJK", + [40] = "stx.hDJK", + [48] = "stx.wDJK", + [56] = "stx.dDJK", + }, + [1] = { + shift = 15, mask = 0x3f, + [0] = "ldx.buDJK", + [8] = "ldx.huDJK", + [16] = "ldx.wuDJK", + [32] = "fldx.sFJK", + [40] = "fldx.dFJK", + [48] = "fstx.sFJK", + [56] = "fstx.dFJK", + }, + [2] = { + shift = 15, mask = 0x3f, + [46] = "sc.wDJW", + }, + [3] = { + shift = 15, mask = 0x3f, + [40] = "fldgt.sFJK", + [41] = "fldgt.dFJK", + [42] = "fldle.sFJK", + [43] = "fldle.dFJK", + [44] = "fstgt.sFJK", + [45] = "fstgt.dFJK", + [46] = "fstle.sFJK", + [47] = "fstle.dFJK", + [48] = "ldgt.bDJK", + [49] = "ldgt.hDJK", + [50] = "ldgt.wDJK", + [51] = "ldgt.dDJK", + [52] = "ldle.bDJK", + [53] = "ldle.hDJK", + [54] = "ldle.wDJK", + [55] = "ldle.dDJK", + [56] = "stgt.bDJK", + [57] = "stgt.hDJK", + [58] = "stgt.wDJK", + [59] = "stgt.dDJK", + [60] = "stle.bDJK", + [61] = "stle.hDJK", + [62] = "stle.wDJK", + [63] = "stle.dDJK", + }, + }, + }, + [2] = { + shift = 26, mask = 0x7, + [0] = "beqzJL", + [1] = "bnezJL", + [2] = { shift = 8, mask = 3, [0] = "bceqzAL", "bcnezAL", }, + [3] = "jirlDJO", + [4] = "bP", + [5] = "blP", + [6] = "beqJDO", + [7] = "bneJDO", + }, + [3] = { + shift = 26, mask = 0x7, + [0] = "bltJDO", + [1] = "bgeJDO", + [2] = "bltuJDO", + [3] = "bgeuJDO", + }, } -local map_init = { - shift = 26, mask = 63, - [0] = map_26_0, - [2] = map_fp, - [3] = map_fcmp, - [4] = "addu16i.dDJY", - [5] = map_long_i_5, - [6] = map_long_i_6, - [7] = map_long_i_7, - [8] = map_ldst1_8, - [9] = map_ldst1_9, - [10] = map_ldst1_10, - [14] = map_ldst0_14, - [16] = "beqzJL", - [17] = "bnezJL", - [18] = { shift = 8, mask = 3, [0] = "bceqzAL", "bcnezAL", }, - [19] = "jirlDJa", - [20] = "bP", - [21] = "blP", - [22] = "beqJDO", - [23] = "bneJDO", - [24] = "bltJDO", - [25] = "bgeJDO", - [26] = "bltuJDO", - [27] = "bgeuJDO", -} +local map_init = map_zero_31_31 ------------------------------------------------------------------------------ @@ -474,6 +494,12 @@ local map_gpr = { "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", } +local map_fpr = { + [0] = "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", +} ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. @@ -505,148 +531,128 @@ local function get_le(ctx) return bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0) end --- Decode imm. -local function decode_si_imm(imm, bits, scale, signed, mask) - local n = tonumber(imm) - if n then - local m = arshift(n, scale) - if lshift(m, scale) == n then - if signed then - local s = arshift(band(m, mask), bits-1) - if s == 0 then - return m - elseif s == 1 then - return -(band(bnot(m), mask)+1) - end - else - if arshift(m, bits) == 0 then - return m - end - end - end +-- Decode a signed immediate value +local function decode_simm(ctx, op, shift, bits, hex_digits) + local mask = lshift(1, bits) - 1 + local val = band(rshift(op, shift), mask) + if band(val, lshift(1, bits-1)) ~= 0 then + val = val - lshift(1, bits) + end + ctx.rel = val + if hex_digits then + local fmt = "%d(0x%0"..hex_digits.."x)" + return format(fmt, val, band(val, mask)) + else + return format("%d(0x%x)", val, band(val, mask)) end end +-- Similar for unsigned immediate (no sign extension) +local function decode_uimm(ctx, op, shift, bits, hex_digits) + local mask = lshift(1, bits) - 1 + local val = band(rshift(op, shift), mask) + ctx.rel = val + if hex_digits then + local fmt = "%d(0x%0"..hex_digits.."x)" + return format(fmt, val, val) + else + return format("%d(0x%x)", val, val) + end +end + +-- Decode a PC-relative branch offset +local function decode_offs(ctx, offs, bits) + local mask = lshift(1, bits) - 1 + if band(offs, lshift(1, bits-1)) ~= 0 then + offs = offs - lshift(1, bits) + end + -- branch offsets are in units of 4 bytes (<< 2) + local target = ctx.addr + ctx.pos + lshift(offs, 2) + ctx.rel = target + return format("0x%08x", target) +end + -- Disassemble a single instruction. local function disass_ins(ctx) local op = ctx:get() local operands = {} - local last = nil ctx.op = op ctx.rel = nil - local opat = ctx.map_pri[rshift(op, 26)] + local opat = ctx.map_pri[band(rshift(op, ctx.map_pri.shift), ctx.map_pri.mask)] while type(opat) ~= "string" do if not opat then return unknown(ctx) end opat = opat[band(rshift(op, opat.shift), opat.mask)] end - local name, pat = match(opat, "^([a-z0-9_.]*)(.*)") - local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)") - if altname then pat = pat2 end + local name, pat = match(opat, "^([a-z0-9.]*)(.*)") for p in gmatch(pat, ".") do local x = nil - if p == "D" then - x = map_gpr[band(rshift(op, 0), 31)] - elseif p == "J" then - x = map_gpr[band(rshift(op, 5), 31)] - elseif p == "K" then - x = map_gpr[band(rshift(op, 10), 31)] - elseif p == "F" then - x = "f"..band(rshift(op, 0), 31) - elseif p == "G" then - x = "f"..band(rshift(op, 5), 31) - elseif p == "H" then - x = "f"..band(rshift(op, 10), 31) - elseif p == "i" then - x = "f"..band(rshift(op, 15), 31) - elseif p == "S" then - x = "fcsr"..band(rshift(op, 0), 31) - elseif p == "R" then - x = "fcsr"..band(rshift(op, 5), 31) - elseif p == "E" then - x = "fcc"..band(rshift(op, 0), 7) - elseif p == "A" then - x = "fcc"..band(rshift(op, 5), 7) - elseif p == "I" then - x = "fcc"..band(rshift(op, 15), 7) + if p == "D" then -- rd + x = map_gpr[band(op, 0x1f)] + elseif p == "J" then -- rj + x = map_gpr[band(rshift(op, 5), 0x1f)] + elseif p == "K" then -- rk + x = map_gpr[band(rshift(op, 10), 0x1f)] + elseif p == "F" then -- fd + x = map_fpr[band(op, 0x1f)] + elseif p == "G" then -- fj + x = map_fpr[band(rshift(op, 5), 0x1f)] + elseif p == "H" then -- fk + x = map_fpr[band(rshift(op, 10), 0x1f)] + elseif p == "i" then -- fa + x = map_fpr[band(rshift(op, 15), 0x1f)] + elseif p == "S" then -- fcsr + x = "fcsr"..band(op, 0x1f) + elseif p == "R" then -- fcsr + x = "fcsr"..band(rshift(op, 5), 0x1f) + elseif p == "E" then -- cd + x = "fcc"..band(op, 0x7) + elseif p == "A" then -- cj + x = "fcc"..band(rshift(op, 5), 0x7) + elseif p == "I" then -- ca + x = "fcc"..band(rshift(op, 15), 0x7) elseif p == "Q" then -- sa2 - x = band(rshift(op, 15), 3) - ctx.rel = x - x = format("%d", x) + x = decode_uimm(ctx, op, 15, 2, nil) elseif p == "B" then -- sa3 - x = band(rshift(op, 15), 7) - ctx.rel = x - x = format("%d", x) + x = decode_uimm(ctx, op, 15, 3, nil) elseif p == "M" then -- msbw - x = band(rshift(op, 16), 31) - ctx.rel = x - x = format("%d(0x%x)", x, x) + x = decode_uimm(ctx, op, 16, 5, 2) elseif p == "N" then -- msbd - x = band(rshift(op, 16), 63) - ctx.rel = x - x = format("%d(0x%x)", x, x) + x = decode_uimm(ctx, op, 16, 6, 2) elseif p == "U" then -- ui5 - x = band(rshift(op, 10), 31) - ctx.rel = x - x = format("%d(0x%x)", x, x) + x = decode_uimm(ctx, op, 10, 5, 2) elseif p == "V" then -- ui6 - x = band(rshift(op, 10), 63) - ctx.rel = x - x = format("%d(0x%x)", x, x) + x = decode_uimm(ctx, op, 10, 6, 2) elseif p == "T" then -- ui12 - x = band(rshift(op, 10), 4095) - ctx.rel = x - x = format("%d(0x%x)", x, x) + x = decode_uimm(ctx, op, 10, 12, 3) elseif p == "W" then -- si14 - x = band(rshift(op, 10), 16383) - x = decode_si_imm(x, 14, 0, true, 0x3fff) - ctx.rel = x - x = format("%d(0x%04x)", x, band(x, 0x3fff)) + x = decode_simm(ctx, op, 10, 14, 4) elseif p == "X" then -- si12 - x = band(rshift(op, 10), 4095) - x = decode_si_imm(x, 12, 0, true, 0xfff) - ctx.rel = x - x = format("%d(0x%03x)", x, band(x, 0xfff)) - elseif p == "o" then - local disp = band((rshift(op, 10)), 0xfff) - operands[#operands] = format("%s, %d", last, disp) + x = decode_simm(ctx, op, 10, 12, 3) elseif p == "Y" then -- si16 - x = band(rshift(op, 10), 65535) - x = decode_si_imm(x, 16, 0, true, 0xffff) - ctx.rel = x - x = format("%d(0x%04x)", x, band(x, 0xffff)) + x = decode_simm(ctx, op, 10, 16, 4) elseif p == "Z" then -- si20 - x = band(rshift(op, 10), 1048575) - x = decode_si_imm(x, 20, 0, true, 0xfffff) - ctx.rel = x - x = format("%d(0x%05x)", x, band(x, 0xfffff)) + x = decode_simm(ctx, op, 5, 20, 5) elseif p == "C" then -- code - x = band(rshift(op, 0), 32767) + x = band(op, 0x1f) elseif p == "O" then -- offs[15:0] - x = band(rshift(op, 10), 65535) - x = decode_si_imm(x, 16, 0, true, 0xffff) - ctx.rel = x - x = format("%d(0x%04x)", x, band(x, 0xffff)) + if name == "jirl" then + x = decode_simm(ctx, op, 10, 16, 4) + else + local offs = band(rshift(op, 10), 0xffff) + x = decode_offs(ctx, offs, 16) + end elseif p == "L" then -- offs[15:0] + offs[20:16] - x = lshift(band(op, 31), 16) + band(rshift(op, 10), 65535) - x = decode_si_imm(x, 21, 0, true, 0x1fffff) - ctx.rel = x - x = format("%d(0x%06x)", x, band(x, 0x1fffff)) + local offs = lshift(band(op, 0x1f), 16) + band(rshift(op, 10), 0xffff) + x = decode_offs(ctx, offs, 21) elseif p == "P" then -- offs[15:0] + offs[25:16] - x = lshift(band(op, 1023), 16) + band(rshift(op, 10), 65535) - x = decode_si_imm(x, 26, 0, true, 0x3ffffff) - ctx.rel = x - x = format("%d(0x%07x)", x, band(x, 0x3ffffff)) - elseif p == "a" then - x = band(rshift(op, 10), 65535) - x = decode_si_imm(x, 16, 0, true, 0xffff) - ctx.rel = x - x = format("%d(0x%04x)", x, band(x, 0xffff)) + local offs = lshift(band(op, 0x3ff), 16) + band(rshift(op, 10), 0xffff) + x = decode_offs(ctx, offs, 26) else assert(false) end - if x then operands[#operands+1] = x; last = x end + if x then operands[#operands+1] = x end end return putop(ctx, name, operands) @@ -686,7 +692,7 @@ end -- Return register name for RID. local function regname(r) if r < 32 then return map_gpr[r] end - return "f"..(r-32) + return map_fpr[r-32] end -- Public module functions.