diff options
Diffstat (limited to 'src/jit/dis_mips.lua')
| -rw-r--r-- | src/jit/dis_mips.lua | 372 |
1 files changed, 319 insertions, 53 deletions
diff --git a/src/jit/dis_mips.lua b/src/jit/dis_mips.lua index ad3dbe4d..fece8937 100644 --- a/src/jit/dis_mips.lua +++ b/src/jit/dis_mips.lua | |||
| @@ -19,13 +19,34 @@ local band, bor, tohex = bit.band, bit.bor, bit.tohex | |||
| 19 | local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift | 19 | local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift |
| 20 | 20 | ||
| 21 | ------------------------------------------------------------------------------ | 21 | ------------------------------------------------------------------------------ |
| 22 | -- Primary and extended opcode maps | 22 | -- Extended opcode maps common to all MIPS releases |
| 23 | ------------------------------------------------------------------------------ | 23 | ------------------------------------------------------------------------------ |
| 24 | 24 | ||
| 25 | local map_movci = { shift = 16, mask = 1, [0] = "movfDSC", "movtDSC", } | ||
| 26 | local map_srl = { shift = 21, mask = 1, [0] = "srlDTA", "rotrDTA", } | 25 | local map_srl = { shift = 21, mask = 1, [0] = "srlDTA", "rotrDTA", } |
| 27 | local map_srlv = { shift = 6, mask = 1, [0] = "srlvDTS", "rotrvDTS", } | 26 | local map_srlv = { shift = 6, mask = 1, [0] = "srlvDTS", "rotrvDTS", } |
| 28 | 27 | ||
| 28 | local map_cop0 = { | ||
| 29 | shift = 25, mask = 1, | ||
| 30 | [0] = { | ||
| 31 | shift = 21, mask = 15, | ||
| 32 | [0] = "mfc0TDW", [4] = "mtc0TDW", | ||
| 33 | [10] = "rdpgprDT", | ||
| 34 | [11] = { shift = 5, mask = 1, [0] = "diT0", "eiT0", }, | ||
| 35 | [14] = "wrpgprDT", | ||
| 36 | }, { | ||
| 37 | shift = 0, mask = 63, | ||
| 38 | [1] = "tlbr", [2] = "tlbwi", [6] = "tlbwr", [8] = "tlbp", | ||
| 39 | [24] = "eret", [31] = "deret", | ||
| 40 | [32] = "wait", | ||
| 41 | }, | ||
| 42 | } | ||
| 43 | |||
| 44 | ------------------------------------------------------------------------------ | ||
| 45 | -- Primary and extended opcode maps for MIPS R1-R5 | ||
| 46 | ------------------------------------------------------------------------------ | ||
| 47 | |||
| 48 | local map_movci = { shift = 16, mask = 1, [0] = "movfDSC", "movtDSC", } | ||
| 49 | |||
| 29 | local map_special = { | 50 | local map_special = { |
| 30 | shift = 0, mask = 63, | 51 | shift = 0, mask = 63, |
| 31 | [0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" }, | 52 | [0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" }, |
| @@ -34,15 +55,17 @@ local map_special = { | |||
| 34 | "jrS", "jalrD1S", "movzDST", "movnDST", | 55 | "jrS", "jalrD1S", "movzDST", "movnDST", |
| 35 | "syscallY", "breakY", false, "sync", | 56 | "syscallY", "breakY", false, "sync", |
| 36 | "mfhiD", "mthiS", "mfloD", "mtloS", | 57 | "mfhiD", "mthiS", "mfloD", "mtloS", |
| 37 | false, false, false, false, | 58 | "dsllvDST", false, "dsrlvDST", "dsravDST", |
| 38 | "multST", "multuST", "divST", "divuST", | 59 | "multST", "multuST", "divST", "divuST", |
| 39 | false, false, false, false, | 60 | "dmultST", "dmultuST", "ddivST", "ddivuST", |
| 40 | "addDST", "addu|moveDST0", "subDST", "subu|neguDS0T", | 61 | "addDST", "addu|moveDST0", "subDST", "subu|neguDS0T", |
| 41 | "andDST", "orDST", "xorDST", "nor|notDST0", | 62 | "andDST", "or|moveDST0", "xorDST", "nor|notDST0", |
| 42 | false, false, "sltDST", "sltuDST", | 63 | false, false, "sltDST", "sltuDST", |
| 43 | false, false, false, false, | 64 | "daddDST", "dadduDST", "dsubDST", "dsubuDST", |
| 44 | "tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ", | 65 | "tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ", |
| 45 | "teqSTZ", false, "tneSTZ", | 66 | "teqSTZ", false, "tneSTZ", false, |
| 67 | "dsllDTA", false, "dsrlDTA", "dsraDTA", | ||
| 68 | "dsll32DTA", false, "dsrl32DTA", "dsra32DTA", | ||
| 46 | } | 69 | } |
| 47 | 70 | ||
| 48 | local map_special2 = { | 71 | local map_special2 = { |
| @@ -60,11 +83,17 @@ local map_bshfl = { | |||
| 60 | [24] = "sehDT", | 83 | [24] = "sehDT", |
| 61 | } | 84 | } |
| 62 | 85 | ||
| 86 | local map_dbshfl = { | ||
| 87 | shift = 6, mask = 31, | ||
| 88 | [2] = "dsbhDT", | ||
| 89 | [5] = "dshdDT", | ||
| 90 | } | ||
| 91 | |||
| 63 | local map_special3 = { | 92 | local map_special3 = { |
| 64 | shift = 0, mask = 63, | 93 | shift = 0, mask = 63, |
| 65 | [0] = "extTSAK", [4] = "insTSAL", | 94 | [0] = "extTSAK", [1] = "dextmTSAP", [3] = "dextTSAK", |
| 66 | [32] = map_bshfl, | 95 | [4] = "insTSAL", [6] = "dinsuTSEQ", [7] = "dinsTSAL", |
| 67 | [59] = "rdhwrTD", | 96 | [32] = map_bshfl, [36] = map_dbshfl, [59] = "rdhwrTD", |
| 68 | } | 97 | } |
| 69 | 98 | ||
| 70 | local map_regimm = { | 99 | local map_regimm = { |
| @@ -79,22 +108,6 @@ local map_regimm = { | |||
| 79 | false, false, false, "synciSO", | 108 | false, false, false, "synciSO", |
| 80 | } | 109 | } |
| 81 | 110 | ||
| 82 | local map_cop0 = { | ||
| 83 | shift = 25, mask = 1, | ||
| 84 | [0] = { | ||
| 85 | shift = 21, mask = 15, | ||
| 86 | [0] = "mfc0TDW", [4] = "mtc0TDW", | ||
| 87 | [10] = "rdpgprDT", | ||
| 88 | [11] = { shift = 5, mask = 1, [0] = "diT0", "eiT0", }, | ||
| 89 | [14] = "wrpgprDT", | ||
| 90 | }, { | ||
| 91 | shift = 0, mask = 63, | ||
| 92 | [1] = "tlbr", [2] = "tlbwi", [6] = "tlbwr", [8] = "tlbp", | ||
| 93 | [24] = "eret", [31] = "deret", | ||
| 94 | [32] = "wait", | ||
| 95 | }, | ||
| 96 | } | ||
| 97 | |||
| 98 | local map_cop1s = { | 111 | local map_cop1s = { |
| 99 | shift = 0, mask = 63, | 112 | shift = 0, mask = 63, |
| 100 | [0] = "add.sFGH", "sub.sFGH", "mul.sFGH", "div.sFGH", | 113 | [0] = "add.sFGH", "sub.sFGH", "mul.sFGH", "div.sFGH", |
| @@ -178,8 +191,8 @@ local map_cop1bc = { | |||
| 178 | 191 | ||
| 179 | local map_cop1 = { | 192 | local map_cop1 = { |
| 180 | shift = 21, mask = 31, | 193 | shift = 21, mask = 31, |
| 181 | [0] = "mfc1TG", false, "cfc1TG", "mfhc1TG", | 194 | [0] = "mfc1TG", "dmfc1TG", "cfc1TG", "mfhc1TG", |
| 182 | "mtc1TG", false, "ctc1TG", "mthc1TG", | 195 | "mtc1TG", "dmtc1TG", "ctc1TG", "mthc1TG", |
| 183 | map_cop1bc, false, false, false, | 196 | map_cop1bc, false, false, false, |
| 184 | false, false, false, false, | 197 | false, false, false, false, |
| 185 | map_cop1s, map_cop1d, false, false, | 198 | map_cop1s, map_cop1d, false, false, |
| @@ -213,16 +226,218 @@ local map_pri = { | |||
| 213 | "andiTSU", "ori|liTS0U", "xoriTSU", "luiTU", | 226 | "andiTSU", "ori|liTS0U", "xoriTSU", "luiTU", |
| 214 | map_cop0, map_cop1, false, map_cop1x, | 227 | map_cop0, map_cop1, false, map_cop1x, |
| 215 | "beql|beqzlST0B", "bnel|bnezlST0B", "blezlSB", "bgtzlSB", | 228 | "beql|beqzlST0B", "bnel|bnezlST0B", "blezlSB", "bgtzlSB", |
| 216 | false, false, false, false, | 229 | "daddiTSI", "daddiuTSI", false, false, |
| 217 | map_special2, false, false, map_special3, | 230 | map_special2, "jalxJ", false, map_special3, |
| 218 | "lbTSO", "lhTSO", "lwlTSO", "lwTSO", | 231 | "lbTSO", "lhTSO", "lwlTSO", "lwTSO", |
| 219 | "lbuTSO", "lhuTSO", "lwrTSO", false, | 232 | "lbuTSO", "lhuTSO", "lwrTSO", false, |
| 220 | "sbTSO", "shTSO", "swlTSO", "swTSO", | 233 | "sbTSO", "shTSO", "swlTSO", "swTSO", |
| 221 | false, false, "swrTSO", "cacheNSO", | 234 | false, false, "swrTSO", "cacheNSO", |
| 222 | "llTSO", "lwc1HSO", "lwc2TSO", "prefNSO", | 235 | "llTSO", "lwc1HSO", "lwc2TSO", "prefNSO", |
| 223 | false, "ldc1HSO", "ldc2TSO", false, | 236 | false, "ldc1HSO", "ldc2TSO", "ldTSO", |
| 224 | "scTSO", "swc1HSO", "swc2TSO", false, | 237 | "scTSO", "swc1HSO", "swc2TSO", false, |
| 225 | false, "sdc1HSO", "sdc2TSO", false, | 238 | false, "sdc1HSO", "sdc2TSO", "sdTSO", |
| 239 | } | ||
| 240 | |||
| 241 | ------------------------------------------------------------------------------ | ||
| 242 | -- Primary and extended opcode maps for MIPS R6 | ||
| 243 | ------------------------------------------------------------------------------ | ||
| 244 | |||
| 245 | local map_mul_r6 = { shift = 6, mask = 3, [2] = "mulDST", [3] = "muhDST" } | ||
| 246 | local map_mulu_r6 = { shift = 6, mask = 3, [2] = "muluDST", [3] = "muhuDST" } | ||
| 247 | local map_div_r6 = { shift = 6, mask = 3, [2] = "divDST", [3] = "modDST" } | ||
| 248 | local map_divu_r6 = { shift = 6, mask = 3, [2] = "divuDST", [3] = "moduDST" } | ||
| 249 | local map_dmul_r6 = { shift = 6, mask = 3, [2] = "dmulDST", [3] = "dmuhDST" } | ||
| 250 | local map_dmulu_r6 = { shift = 6, mask = 3, [2] = "dmuluDST", [3] = "dmuhuDST" } | ||
| 251 | local map_ddiv_r6 = { shift = 6, mask = 3, [2] = "ddivDST", [3] = "dmodDST" } | ||
| 252 | local map_ddivu_r6 = { shift = 6, mask = 3, [2] = "ddivuDST", [3] = "dmoduDST" } | ||
| 253 | |||
| 254 | local map_special_r6 = { | ||
| 255 | shift = 0, mask = 63, | ||
| 256 | [0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" }, | ||
| 257 | false, map_srl, "sraDTA", | ||
| 258 | "sllvDTS", false, map_srlv, "sravDTS", | ||
| 259 | "jrS", "jalrD1S", false, false, | ||
| 260 | "syscallY", "breakY", false, "sync", | ||
| 261 | "clzDS", "cloDS", "dclzDS", "dcloDS", | ||
| 262 | "dsllvDST", "dlsaDSTA", "dsrlvDST", "dsravDST", | ||
| 263 | map_mul_r6, map_mulu_r6, map_div_r6, map_divu_r6, | ||
| 264 | map_dmul_r6, map_dmulu_r6, map_ddiv_r6, map_ddivu_r6, | ||
| 265 | "addDST", "addu|moveDST0", "subDST", "subu|neguDS0T", | ||
| 266 | "andDST", "or|moveDST0", "xorDST", "nor|notDST0", | ||
| 267 | false, false, "sltDST", "sltuDST", | ||
| 268 | "daddDST", "dadduDST", "dsubDST", "dsubuDST", | ||
| 269 | "tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ", | ||
| 270 | "teqSTZ", "seleqzDST", "tneSTZ", "selnezDST", | ||
| 271 | "dsllDTA", false, "dsrlDTA", "dsraDTA", | ||
| 272 | "dsll32DTA", false, "dsrl32DTA", "dsra32DTA", | ||
| 273 | } | ||
| 274 | |||
| 275 | local map_bshfl_r6 = { | ||
| 276 | shift = 9, mask = 3, | ||
| 277 | [1] = "alignDSTa", | ||
| 278 | _ = { | ||
| 279 | shift = 6, mask = 31, | ||
| 280 | [0] = "bitswapDT", | ||
| 281 | [2] = "wsbhDT", | ||
| 282 | [16] = "sebDT", | ||
| 283 | [24] = "sehDT", | ||
| 284 | } | ||
| 285 | } | ||
| 286 | |||
| 287 | local map_dbshfl_r6 = { | ||
| 288 | shift = 9, mask = 3, | ||
| 289 | [1] = "dalignDSTa", | ||
| 290 | _ = { | ||
| 291 | shift = 6, mask = 31, | ||
| 292 | [0] = "dbitswapDT", | ||
| 293 | [2] = "dsbhDT", | ||
| 294 | [5] = "dshdDT", | ||
| 295 | } | ||
| 296 | } | ||
| 297 | |||
| 298 | local map_special3_r6 = { | ||
| 299 | shift = 0, mask = 63, | ||
| 300 | [0] = "extTSAK", [1] = "dextmTSAP", [3] = "dextTSAK", | ||
| 301 | [4] = "insTSAL", [6] = "dinsuTSEQ", [7] = "dinsTSAL", | ||
| 302 | [32] = map_bshfl_r6, [36] = map_dbshfl_r6, [59] = "rdhwrTD", | ||
| 303 | } | ||
| 304 | |||
| 305 | local map_regimm_r6 = { | ||
| 306 | shift = 16, mask = 31, | ||
| 307 | [0] = "bltzSB", [1] = "bgezSB", | ||
| 308 | [6] = "dahiSI", [30] = "datiSI", | ||
| 309 | [23] = "sigrieI", [31] = "synciSO", | ||
| 310 | } | ||
| 311 | |||
| 312 | local map_pcrel_r6 = { | ||
| 313 | shift = 19, mask = 3, | ||
| 314 | [0] = "addiupcS2", "lwpcS2", "lwupcS2", { | ||
| 315 | shift = 18, mask = 1, | ||
| 316 | [0] = "ldpcS3", { shift = 16, mask = 3, [2] = "auipcSI", [3] = "aluipcSI" } | ||
| 317 | } | ||
| 318 | } | ||
| 319 | |||
| 320 | local map_cop1s_r6 = { | ||
| 321 | shift = 0, mask = 63, | ||
| 322 | [0] = "add.sFGH", "sub.sFGH", "mul.sFGH", "div.sFGH", | ||
| 323 | "sqrt.sFG", "abs.sFG", "mov.sFG", "neg.sFG", | ||
| 324 | "round.l.sFG", "trunc.l.sFG", "ceil.l.sFG", "floor.l.sFG", | ||
| 325 | "round.w.sFG", "trunc.w.sFG", "ceil.w.sFG", "floor.w.sFG", | ||
| 326 | "sel.sFGH", false, false, false, | ||
| 327 | "seleqz.sFGH", "recip.sFG", "rsqrt.sFG", "selnez.sFGH", | ||
| 328 | "maddf.sFGH", "msubf.sFGH", "rint.sFG", "class.sFG", | ||
| 329 | "min.sFGH", "mina.sFGH", "max.sFGH", "maxa.sFGH", | ||
| 330 | false, "cvt.d.sFG", false, false, | ||
| 331 | "cvt.w.sFG", "cvt.l.sFG", | ||
| 332 | } | ||
| 333 | |||
| 334 | local map_cop1d_r6 = { | ||
| 335 | shift = 0, mask = 63, | ||
| 336 | [0] = "add.dFGH", "sub.dFGH", "mul.dFGH", "div.dFGH", | ||
| 337 | "sqrt.dFG", "abs.dFG", "mov.dFG", "neg.dFG", | ||
| 338 | "round.l.dFG", "trunc.l.dFG", "ceil.l.dFG", "floor.l.dFG", | ||
| 339 | "round.w.dFG", "trunc.w.dFG", "ceil.w.dFG", "floor.w.dFG", | ||
| 340 | "sel.dFGH", false, false, false, | ||
| 341 | "seleqz.dFGH", "recip.dFG", "rsqrt.dFG", "selnez.dFGH", | ||
| 342 | "maddf.dFGH", "msubf.dFGH", "rint.dFG", "class.dFG", | ||
| 343 | "min.dFGH", "mina.dFGH", "max.dFGH", "maxa.dFGH", | ||
| 344 | "cvt.s.dFG", false, false, false, | ||
| 345 | "cvt.w.dFG", "cvt.l.dFG", | ||
| 346 | } | ||
| 347 | |||
| 348 | local map_cop1w_r6 = { | ||
| 349 | shift = 0, mask = 63, | ||
| 350 | [0] = "cmp.af.sFGH", "cmp.un.sFGH", "cmp.eq.sFGH", "cmp.ueq.sFGH", | ||
| 351 | "cmp.lt.sFGH", "cmp.ult.sFGH", "cmp.le.sFGH", "cmp.ule.sFGH", | ||
| 352 | "cmp.saf.sFGH", "cmp.sun.sFGH", "cmp.seq.sFGH", "cmp.sueq.sFGH", | ||
| 353 | "cmp.slt.sFGH", "cmp.sult.sFGH", "cmp.sle.sFGH", "cmp.sule.sFGH", | ||
| 354 | false, "cmp.or.sFGH", "cmp.une.sFGH", "cmp.ne.sFGH", | ||
| 355 | false, false, false, false, | ||
| 356 | false, "cmp.sor.sFGH", "cmp.sune.sFGH", "cmp.sne.sFGH", | ||
| 357 | false, false, false, false, | ||
| 358 | "cvt.s.wFG", "cvt.d.wFG", | ||
| 359 | } | ||
| 360 | |||
| 361 | local map_cop1l_r6 = { | ||
| 362 | shift = 0, mask = 63, | ||
| 363 | [0] = "cmp.af.dFGH", "cmp.un.dFGH", "cmp.eq.dFGH", "cmp.ueq.dFGH", | ||
| 364 | "cmp.lt.dFGH", "cmp.ult.dFGH", "cmp.le.dFGH", "cmp.ule.dFGH", | ||
| 365 | "cmp.saf.dFGH", "cmp.sun.dFGH", "cmp.seq.dFGH", "cmp.sueq.dFGH", | ||
| 366 | "cmp.slt.dFGH", "cmp.sult.dFGH", "cmp.sle.dFGH", "cmp.sule.dFGH", | ||
| 367 | false, "cmp.or.dFGH", "cmp.une.dFGH", "cmp.ne.dFGH", | ||
| 368 | false, false, false, false, | ||
| 369 | false, "cmp.sor.dFGH", "cmp.sune.dFGH", "cmp.sne.dFGH", | ||
| 370 | false, false, false, false, | ||
| 371 | "cvt.s.lFG", "cvt.d.lFG", | ||
| 372 | } | ||
| 373 | |||
| 374 | local map_cop1_r6 = { | ||
| 375 | shift = 21, mask = 31, | ||
| 376 | [0] = "mfc1TG", "dmfc1TG", "cfc1TG", "mfhc1TG", | ||
| 377 | "mtc1TG", "dmtc1TG", "ctc1TG", "mthc1TG", | ||
| 378 | false, "bc1eqzHB", false, false, | ||
| 379 | false, "bc1nezHB", false, false, | ||
| 380 | map_cop1s_r6, map_cop1d_r6, false, false, | ||
| 381 | map_cop1w_r6, map_cop1l_r6, | ||
| 382 | } | ||
| 383 | |||
| 384 | local function maprs_popTS(rs, rt) | ||
| 385 | if rt == 0 then return 0 elseif rs == 0 then return 1 | ||
| 386 | elseif rs == rt then return 2 else return 3 end | ||
| 387 | end | ||
| 388 | |||
| 389 | local map_pop06_r6 = { | ||
| 390 | maprs = maprs_popTS, [0] = "blezSB", "blezalcTB", "bgezalcTB", "bgeucSTB" | ||
| 391 | } | ||
| 392 | local map_pop07_r6 = { | ||
| 393 | maprs = maprs_popTS, [0] = "bgtzSB", "bgtzalcTB", "bltzalcTB", "bltucSTB" | ||
| 394 | } | ||
| 395 | local map_pop26_r6 = { | ||
| 396 | maprs = maprs_popTS, "blezcTB", "bgezcTB", "bgecSTB" | ||
| 397 | } | ||
| 398 | local map_pop27_r6 = { | ||
| 399 | maprs = maprs_popTS, "bgtzcTB", "bltzcTB", "bltcSTB" | ||
| 400 | } | ||
| 401 | |||
| 402 | local function maprs_popS(rs, rt) | ||
| 403 | if rs == 0 then return 0 else return 1 end | ||
| 404 | end | ||
| 405 | |||
| 406 | local map_pop66_r6 = { | ||
| 407 | maprs = maprs_popS, [0] = "jicTI", "beqzcSb" | ||
| 408 | } | ||
| 409 | local map_pop76_r6 = { | ||
| 410 | maprs = maprs_popS, [0] = "jialcTI", "bnezcSb" | ||
| 411 | } | ||
| 412 | |||
| 413 | local function maprs_popST(rs, rt) | ||
| 414 | if rs >= rt then return 0 elseif rs == 0 then return 1 else return 2 end | ||
| 415 | end | ||
| 416 | |||
| 417 | local map_pop10_r6 = { | ||
| 418 | maprs = maprs_popST, [0] = "bovcSTB", "beqzalcTB", "beqcSTB" | ||
| 419 | } | ||
| 420 | local map_pop30_r6 = { | ||
| 421 | maprs = maprs_popST, [0] = "bnvcSTB", "bnezalcTB", "bnecSTB" | ||
| 422 | } | ||
| 423 | |||
| 424 | local map_pri_r6 = { | ||
| 425 | [0] = map_special_r6, map_regimm_r6, "jJ", "jalJ", | ||
| 426 | "beq|beqz|bST00B", "bne|bnezST0B", map_pop06_r6, map_pop07_r6, | ||
| 427 | map_pop10_r6, "addiu|liTS0I", "sltiTSI", "sltiuTSI", | ||
| 428 | "andiTSU", "ori|liTS0U", "xoriTSU", "aui|luiTS0U", | ||
| 429 | map_cop0, map_cop1_r6, false, false, | ||
| 430 | false, false, map_pop26_r6, map_pop27_r6, | ||
| 431 | map_pop30_r6, "daddiuTSI", false, false, | ||
| 432 | false, "dauiTSI", false, map_special3_r6, | ||
| 433 | "lbTSO", "lhTSO", false, "lwTSO", | ||
| 434 | "lbuTSO", "lhuTSO", false, false, | ||
| 435 | "sbTSO", "shTSO", false, "swTSO", | ||
| 436 | false, false, false, false, | ||
| 437 | false, "lwc1HSO", "bc#", false, | ||
| 438 | false, "ldc1HSO", map_pop66_r6, "ldTSO", | ||
| 439 | false, "swc1HSO", "balc#", map_pcrel_r6, | ||
| 440 | false, "sdc1HSO", map_pop76_r6, "sdTSO", | ||
| 226 | } | 441 | } |
| 227 | 442 | ||
| 228 | ------------------------------------------------------------------------------ | 443 | ------------------------------------------------------------------------------ |
| @@ -279,10 +494,14 @@ local function disass_ins(ctx) | |||
| 279 | ctx.op = op | 494 | ctx.op = op |
| 280 | ctx.rel = nil | 495 | ctx.rel = nil |
| 281 | 496 | ||
| 282 | local opat = map_pri[rshift(op, 26)] | 497 | local opat = ctx.map_pri[rshift(op, 26)] |
| 283 | while type(opat) ~= "string" do | 498 | while type(opat) ~= "string" do |
| 284 | if not opat then return unknown(ctx) end | 499 | if not opat then return unknown(ctx) end |
| 285 | opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ | 500 | if opat.maprs then |
| 501 | opat = opat[opat.maprs(band(rshift(op,21),31), band(rshift(op,16),31))] | ||
| 502 | else | ||
| 503 | opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ | ||
| 504 | end | ||
| 286 | end | 505 | end |
| 287 | local name, pat = match(opat, "^([a-z0-9_.]*)(.*)") | 506 | local name, pat = match(opat, "^([a-z0-9_.]*)(.*)") |
| 288 | local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)") | 507 | local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)") |
| @@ -306,6 +525,10 @@ local function disass_ins(ctx) | |||
| 306 | x = "f"..band(rshift(op, 21), 31) | 525 | x = "f"..band(rshift(op, 21), 31) |
| 307 | elseif p == "A" then | 526 | elseif p == "A" then |
| 308 | x = band(rshift(op, 6), 31) | 527 | x = band(rshift(op, 6), 31) |
| 528 | elseif p == "a" then | ||
| 529 | x = band(rshift(op, 6), 7) | ||
| 530 | elseif p == "E" then | ||
| 531 | x = band(rshift(op, 6), 31) + 32 | ||
| 309 | elseif p == "M" then | 532 | elseif p == "M" then |
| 310 | x = band(rshift(op, 11), 31) | 533 | x = band(rshift(op, 11), 31) |
| 311 | elseif p == "N" then | 534 | elseif p == "N" then |
| @@ -315,10 +538,18 @@ local function disass_ins(ctx) | |||
| 315 | if x == 0 then x = nil end | 538 | if x == 0 then x = nil end |
| 316 | elseif p == "K" then | 539 | elseif p == "K" then |
| 317 | x = band(rshift(op, 11), 31) + 1 | 540 | x = band(rshift(op, 11), 31) + 1 |
| 541 | elseif p == "P" then | ||
| 542 | x = band(rshift(op, 11), 31) + 33 | ||
| 318 | elseif p == "L" then | 543 | elseif p == "L" then |
| 319 | x = band(rshift(op, 11), 31) - last + 1 | 544 | x = band(rshift(op, 11), 31) - last + 1 |
| 545 | elseif p == "Q" then | ||
| 546 | x = band(rshift(op, 11), 31) - last + 33 | ||
| 320 | elseif p == "I" then | 547 | elseif p == "I" then |
| 321 | x = arshift(lshift(op, 16), 16) | 548 | x = arshift(lshift(op, 16), 16) |
| 549 | elseif p == "2" then | ||
| 550 | x = arshift(lshift(op, 13), 11) | ||
| 551 | elseif p == "3" then | ||
| 552 | x = arshift(lshift(op, 14), 11) | ||
| 322 | elseif p == "U" then | 553 | elseif p == "U" then |
| 323 | x = band(op, 0xffff) | 554 | x = band(op, 0xffff) |
| 324 | elseif p == "O" then | 555 | elseif p == "O" then |
| @@ -328,13 +559,22 @@ local function disass_ins(ctx) | |||
| 328 | local index = map_gpr[band(rshift(op, 16), 31)] | 559 | local index = map_gpr[band(rshift(op, 16), 31)] |
| 329 | operands[#operands] = format("%s(%s)", index, last) | 560 | operands[#operands] = format("%s(%s)", index, last) |
| 330 | elseif p == "B" then | 561 | elseif p == "B" then |
| 331 | x = ctx.addr + ctx.pos + arshift(lshift(op, 16), 16)*4 + 4 | 562 | x = ctx.addr + ctx.pos + arshift(lshift(op, 16), 14) + 4 |
| 563 | ctx.rel = x | ||
| 564 | x = format("0x%08x", x) | ||
| 565 | elseif p == "b" then | ||
| 566 | x = ctx.addr + ctx.pos + arshift(lshift(op, 11), 9) + 4 | ||
| 332 | ctx.rel = x | 567 | ctx.rel = x |
| 333 | x = "0x"..tohex(x) | 568 | x = format("0x%08x", x) |
| 569 | elseif p == "#" then | ||
| 570 | x = ctx.addr + ctx.pos + arshift(lshift(op, 6), 4) + 4 | ||
| 571 | ctx.rel = x | ||
| 572 | x = format("0x%08x", x) | ||
| 334 | elseif p == "J" then | 573 | elseif p == "J" then |
| 335 | x = band(ctx.addr + ctx.pos, 0xf0000000) + band(op, 0x03ffffff)*4 | 574 | local a = ctx.addr + ctx.pos |
| 575 | x = a - band(a, 0x0fffffff) + band(op, 0x03ffffff)*4 | ||
| 336 | ctx.rel = x | 576 | ctx.rel = x |
| 337 | x = "0x"..tohex(x) | 577 | x = format("0x%08x", x) |
| 338 | elseif p == "V" then | 578 | elseif p == "V" then |
| 339 | x = band(rshift(op, 8), 7) | 579 | x = band(rshift(op, 8), 7) |
| 340 | if x == 0 then x = nil end | 580 | if x == 0 then x = nil end |
| @@ -384,7 +624,7 @@ local function disass_block(ctx, ofs, len) | |||
| 384 | end | 624 | end |
| 385 | 625 | ||
| 386 | -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). | 626 | -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). |
| 387 | local function create_(code, addr, out) | 627 | local function create(code, addr, out) |
| 388 | local ctx = {} | 628 | local ctx = {} |
| 389 | ctx.code = code | 629 | ctx.code = code |
| 390 | ctx.addr = addr or 0 | 630 | ctx.addr = addr or 0 |
| @@ -393,36 +633,62 @@ local function create_(code, addr, out) | |||
| 393 | ctx.disass = disass_block | 633 | ctx.disass = disass_block |
| 394 | ctx.hexdump = 8 | 634 | ctx.hexdump = 8 |
| 395 | ctx.get = get_be | 635 | ctx.get = get_be |
| 636 | ctx.map_pri = map_pri | ||
| 637 | return ctx | ||
| 638 | end | ||
| 639 | |||
| 640 | local function create_el(code, addr, out) | ||
| 641 | local ctx = create(code, addr, out) | ||
| 642 | ctx.get = get_le | ||
| 643 | return ctx | ||
| 644 | end | ||
| 645 | |||
| 646 | local function create_r6(code, addr, out) | ||
| 647 | local ctx = create(code, addr, out) | ||
| 648 | ctx.map_pri = map_pri_r6 | ||
| 396 | return ctx | 649 | return ctx |
| 397 | end | 650 | end |
| 398 | 651 | ||
| 399 | local function create_el_(code, addr, out) | 652 | local function create_r6_el(code, addr, out) |
| 400 | local ctx = create_(code, addr, out) | 653 | local ctx = create(code, addr, out) |
| 401 | ctx.get = get_le | 654 | ctx.get = get_le |
| 655 | ctx.map_pri = map_pri_r6 | ||
| 402 | return ctx | 656 | return ctx |
| 403 | end | 657 | end |
| 404 | 658 | ||
| 405 | -- Simple API: disassemble code (a string) at address and output via out. | 659 | -- Simple API: disassemble code (a string) at address and output via out. |
| 406 | local function disass_(code, addr, out) | 660 | local function disass(code, addr, out) |
| 407 | create_(code, addr, out):disass() | 661 | create(code, addr, out):disass() |
| 662 | end | ||
| 663 | |||
| 664 | local function disass_el(code, addr, out) | ||
| 665 | create_el(code, addr, out):disass() | ||
| 408 | end | 666 | end |
| 409 | 667 | ||
| 410 | local function disass_el_(code, addr, out) | 668 | local function disass_r6(code, addr, out) |
| 411 | create_el_(code, addr, out):disass() | 669 | create_r6(code, addr, out):disass() |
| 670 | end | ||
| 671 | |||
| 672 | local function disass_r6_el(code, addr, out) | ||
| 673 | create_r6_el(code, addr, out):disass() | ||
| 412 | end | 674 | end |
| 413 | 675 | ||
| 414 | -- Return register name for RID. | 676 | -- Return register name for RID. |
| 415 | local function regname_(r) | 677 | local function regname(r) |
| 416 | if r < 32 then return map_gpr[r] end | 678 | if r < 32 then return map_gpr[r] end |
| 417 | return "f"..(r-32) | 679 | return "f"..(r-32) |
| 418 | end | 680 | end |
| 419 | 681 | ||
| 420 | -- Public module functions. | 682 | -- Public module functions. |
| 421 | module(...) | 683 | return { |
| 422 | 684 | create = create, | |
| 423 | create = create_ | 685 | create_el = create_el, |
| 424 | create_el = create_el_ | 686 | create_r6 = create_r6, |
| 425 | disass = disass_ | 687 | create_r6_el = create_r6_el, |
| 426 | disass_el = disass_el_ | 688 | disass = disass, |
| 427 | regname = regname_ | 689 | disass_el = disass_el, |
| 690 | disass_r6 = disass_r6, | ||
| 691 | disass_r6_el = disass_r6_el, | ||
| 692 | regname = regname | ||
| 693 | } | ||
| 428 | 694 | ||
