aboutsummaryrefslogtreecommitdiff
path: root/src/jit/dis_ppc.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/jit/dis_ppc.lua')
-rw-r--r--src/jit/dis_ppc.lua117
1 files changed, 58 insertions, 59 deletions
diff --git a/src/jit/dis_ppc.lua b/src/jit/dis_ppc.lua
index d8f4cfb78..90eef9408 100644
--- a/src/jit/dis_ppc.lua
+++ b/src/jit/dis_ppc.lua
@@ -17,8 +17,7 @@ local byte, format = string.byte, string.format
17local match, gmatch, gsub = string.match, string.gmatch, string.gsub 17local match, gmatch, gsub = string.match, string.gmatch, string.gsub
18local concat = table.concat 18local concat = table.concat
19local bit = require("bit") 19local bit = require("bit")
20local band, bor, tohex = bit.band, bit.bor, bit.tohex 20local tohex = bit.tohex
21local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
22 21
23------------------------------------------------------------------------------ 22------------------------------------------------------------------------------
24-- Primary and extended opcode maps 23-- Primary and extended opcode maps
@@ -39,9 +38,9 @@ local map_rlwinm = setmetatable({
39 shift = 0, mask = -1, 38 shift = 0, mask = -1,
40}, 39},
41{ __index = function(t, x) 40{ __index = function(t, x)
42 local rot = band(rshift(x, 11), 31) 41 local rot = (x >> 11) & 31
43 local mb = band(rshift(x, 6), 31) 42 local mb = (x >> 6) & 31
44 local me = band(rshift(x, 1), 31) 43 local me = (x >> 1) & 31
45 if mb == 0 and me == 31-rot then 44 if mb == 0 and me == 31-rot then
46 return "slwiRR~A." 45 return "slwiRR~A."
47 elseif me == 31 and mb == 32-rot then 46 elseif me == 31 and mb == 32-rot then
@@ -167,7 +166,7 @@ local map_ext = setmetatable({
167 [539] = "srdRR~R.", 166 [539] = "srdRR~R.",
168}, 167},
169{ __index = function(t, x) 168{ __index = function(t, x)
170 if band(x, 31) == 15 then return "iselRRRC" end 169 if x & 31 == 15 then return "iselRRRC" end
171 end 170 end
172}) 171})
173 172
@@ -386,9 +385,9 @@ local map_cond = { [0] = "lt", "gt", "eq", "so", "ge", "le", "ne", "ns", }
386-- Format a condition bit. 385-- Format a condition bit.
387local function condfmt(cond) 386local function condfmt(cond)
388 if cond <= 3 then 387 if cond <= 3 then
389 return map_cond[band(cond, 3)] 388 return map_cond[cond & 3]
390 else 389 else
391 return format("4*cr%d+%s", rshift(cond, 2), map_cond[band(cond, 3)]) 390 return format("4*cr%d+%s", cond >> 2, map_cond[cond & 3])
392 end 391 end
393end 392end
394 393
@@ -421,17 +420,17 @@ end
421local function disass_ins(ctx) 420local function disass_ins(ctx)
422 local pos = ctx.pos 421 local pos = ctx.pos
423 local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) 422 local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
424 local op = bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3) 423 local op = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3
425 local operands = {} 424 local operands = {}
426 local last = nil 425 local last = nil
427 local rs = 21 426 local rs = 21
428 ctx.op = op 427 ctx.op = op
429 ctx.rel = nil 428 ctx.rel = nil
430 429
431 local opat = map_pri[rshift(b0, 2)] 430 local opat = map_pri[b0 >> 2]
432 while type(opat) ~= "string" do 431 while type(opat) != "string" do
433 if not opat then return unknown(ctx) end 432 if not opat then return unknown(ctx) end
434 opat = opat[band(rshift(op, opat.shift), opat.mask)] 433 opat = opat[(op >> opat.shift) & opat.mask]
435 end 434 end
436 local name, pat = match(opat, "^([a-z0-9_.]*)(.*)") 435 local name, pat = match(opat, "^([a-z0-9_.]*)(.*)")
437 local altname, pat2 = match(pat, "|([a-z0-9_.]*)(.*)") 436 local altname, pat2 = match(pat, "|([a-z0-9_.]*)(.*)")
@@ -440,84 +439,84 @@ local function disass_ins(ctx)
440 for p in gmatch(pat, ".") do 439 for p in gmatch(pat, ".") do
441 local x = nil 440 local x = nil
442 if p == "R" then 441 if p == "R" then
443 x = map_gpr[band(rshift(op, rs), 31)] 442 x = map_gpr[(op >> rs) & 31]
444 rs = rs - 5 443 rs -= 5
445 elseif p == "F" then 444 elseif p == "F" then
446 x = "f"..band(rshift(op, rs), 31) 445 x = "f"..((op >> rs) & 31)
447 rs = rs - 5 446 rs -= 5
448 elseif p == "A" then 447 elseif p == "A" then
449 x = band(rshift(op, rs), 31) 448 x = (op >> rs) & 31
450 rs = rs - 5 449 rs -= 5
451 elseif p == "S" then 450 elseif p == "S" then
452 x = arshift(lshift(op, 27-rs), 27) 451 x = (op << 27-rs) ~>> 27
453 rs = rs - 5 452 rs -= 5
454 elseif p == "I" then 453 elseif p == "I" then
455 x = arshift(lshift(op, 16), 16) 454 x = (op << 16) ~>> 16
456 elseif p == "U" then 455 elseif p == "U" then
457 x = band(op, 0xffff) 456 x = op & 0xffff
458 elseif p == "D" or p == "E" then 457 elseif p == "D" or p == "E" then
459 local disp = arshift(lshift(op, 16), 16) 458 local disp = (op << 16) ~>> 16
460 if p == "E" then disp = band(disp, -4) end 459 if p == "E" then disp &= -4 end
461 if last == "r0" then last = "0" end 460 if last == "r0" then last = "0" end
462 operands[#operands] = format("%d(%s)", disp, last) 461 operands[#operands] = format("%d(%s)", disp, last)
463 elseif p >= "2" and p <= "8" then 462 elseif p >= "2" and p <= "8" then
464 local disp = band(rshift(op, rs), 31) * p 463 local disp = ((op >> rs) & 31) * (byte(p) - 0x30)
465 if last == "r0" then last = "0" end 464 if last == "r0" then last = "0" end
466 operands[#operands] = format("%d(%s)", disp, last) 465 operands[#operands] = format("%d(%s)", disp, last)
467 elseif p == "H" then 466 elseif p == "H" then
468 x = band(rshift(op, rs), 31) + lshift(band(op, 2), 4) 467 x = ((op >> rs) & 31) | ((op & 2) << 4)
469 rs = rs - 5 468 rs -= 5
470 elseif p == "M" then 469 elseif p == "M" then
471 x = band(rshift(op, rs), 31) + band(op, 0x20) 470 x = ((op >> rs) & 31) | (op & 0x20)
472 elseif p == "C" then 471 elseif p == "C" then
473 x = condfmt(band(rshift(op, rs), 31)) 472 x = condfmt((op >> rs) & 31)
474 rs = rs - 5 473 rs -= 5
475 elseif p == "B" then 474 elseif p == "B" then
476 local bo = rshift(op, 21) 475 local bo = op >> 21
477 local cond = band(rshift(op, 16), 31) 476 local cond = (op >> 16) & 31
478 local cn = "" 477 local cn = ""
479 rs = rs - 10 478 rs -= 10
480 if band(bo, 4) == 0 then 479 if bo & 4 == 0 then
481 cn = band(bo, 2) == 0 and "dnz" or "dz" 480 cn = bo & 2 == 0 ? "dnz" : "dz"
482 if band(bo, 0x10) == 0 then 481 if bo & 0x10 == 0 then
483 cn = cn..(band(bo, 8) == 0 and "f" or "t") 482 cn ..= bo & 8 == 0 ? "f" : "t"
483 x = condfmt(cond)
484 end 484 end
485 if band(bo, 0x10) == 0 then x = condfmt(cond) end 485 name ..= bo & 1 == (op >> 15) & 1 ? "-" : "+"
486 name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+") 486 elseif bo & 0x10 == 0 then
487 elseif band(bo, 0x10) == 0 then 487 cn = map_cond[(cond & 3) | ((bo >> 1) & 4)]
488 cn = map_cond[band(cond, 3) + (band(bo, 8) == 0 and 4 or 0)] 488 if cond > 3 then x = "cr"..(cond >> 2) end
489 if cond > 3 then x = "cr"..rshift(cond, 2) end 489 name ..= bo & 1 == (op >> 15) & 1 ? "-" : "+"
490 name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+")
491 end 490 end
492 name = gsub(name, "_", cn) 491 name = gsub(name, "_", cn)
493 elseif p == "J" then 492 elseif p == "J" then
494 x = arshift(lshift(op, 27-rs), 29-rs)*4 493 x = ((op << 27-rs) ~>> 29-rs) << 2
495 if band(op, 2) == 0 then x = ctx.addr + pos + x end 494 if op & 2 == 0 then x = ctx.addr + pos + x end
496 ctx.rel = x 495 ctx.rel = x
497 x = "0x"..tohex(x) 496 x = "0x"..tohex(x)
498 elseif p == "K" then 497 elseif p == "K" then
499 if band(op, 1) ~= 0 then name = name.."l" end 498 if op & 1 != 0 then name ..= "l" end
500 if band(op, 2) ~= 0 then name = name.."a" end 499 if op & 2 != 0 then name ..= "a" end
501 elseif p == "X" or p == "Y" then 500 elseif p == "X" or p == "Y" then
502 x = band(rshift(op, rs+2), 7) 501 x = (op >> rs+2) & 7
503 if x == 0 and p == "Y" then x = nil else x = "cr"..x end 502 x = x == 0 and p == "Y" ? nil : "cr"..x
504 rs = rs - 5 503 rs -= 5
505 elseif p == "W" then 504 elseif p == "W" then
506 x = "cr"..band(op, 7) 505 x = "cr"..(op & 7)
507 elseif p == "Z" then 506 elseif p == "Z" then
508 x = band(rshift(op, rs-4), 255) 507 x = (op >> rs-4) & 0xff
509 rs = rs - 10 508 rs -= 10
510 elseif p == ">" then 509 elseif p == ">" then
511 operands[#operands] = rshift(operands[#operands], 1) 510 operands[#operands] >>= 1
512 elseif p == "0" then 511 elseif p == "0" then
513 if last == "r0" then 512 if last == "r0" then
514 operands[#operands] = nil 513 operands[#operands] = nil
515 if altname then name = altname end 514 if altname then name = altname end
516 end 515 end
517 elseif p == "L" then 516 elseif p == "L" then
518 name = gsub(name, "_", band(op, 0x00200000) ~= 0 and "d" or "w") 517 name = gsub(name, "_", op & 0x00200000 != 0 ? "d" : "w")
519 elseif p == "." then 518 elseif p == "." then
520 if band(op, 1) == 1 then name = name.."." end 519 if op & 1 == 1 then name ..= "." end
521 elseif p == "N" then 520 elseif p == "N" then
522 if op == 0x60000000 then name = "nop"; break end 521 if op == 0x60000000 then name = "nop"; break end
523 elseif p == "~" then 522 elseif p == "~" then
@@ -537,7 +536,7 @@ local function disass_ins(ctx)
537 name = altname 536 name = altname
538 end 537 end
539 elseif p == "-" then 538 elseif p == "-" then
540 rs = rs - 5 539 rs -= 5
541 else 540 else
542 assert(false) 541 assert(false)
543 end 542 end
@@ -553,8 +552,8 @@ end
553local function disass_block(ctx, ofs, len) 552local function disass_block(ctx, ofs, len)
554 if not ofs then ofs = 0 end 553 if not ofs then ofs = 0 end
555 local stop = len and ofs+len or #ctx.code 554 local stop = len and ofs+len or #ctx.code
556 stop = stop - stop % 4 555 stop &= -4
557 ctx.pos = ofs - ofs % 4 556 ctx.pos = ofs & -4
558 ctx.rel = nil 557 ctx.rel = nil
559 while ctx.pos < stop do disass_ins(ctx) end 558 while ctx.pos < stop do disass_ins(ctx) end
560end 559end