aboutsummaryrefslogtreecommitdiff
path: root/src/jit/dis_arm.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/jit/dis_arm.lua')
-rw-r--r--src/jit/dis_arm.lua137
1 files changed, 68 insertions, 69 deletions
diff --git a/src/jit/dis_arm.lua b/src/jit/dis_arm.lua
index 0adc799de..e2334ebbc 100644
--- a/src/jit/dis_arm.lua
+++ b/src/jit/dis_arm.lua
@@ -15,8 +15,7 @@ local sub, byte, format = string.sub, string.byte, string.format
15local match, gmatch = string.match, string.gmatch 15local match, gmatch = string.match, string.gmatch
16local concat = table.concat 16local concat = table.concat
17local bit = require("bit") 17local bit = require("bit")
18local band, bor, ror, tohex = bit.band, bit.bor, bit.ror, bit.tohex 18local ror, tohex = bit.ror, bit.tohex
19local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
20 19
21------------------------------------------------------------------------------ 20------------------------------------------------------------------------------
22-- Opcode maps 21-- Opcode maps
@@ -373,7 +372,7 @@ local map_datar = {
373 [16] = { shift = 7, mask = 1, [0] = map_misc, map_mulh, }, 372 [16] = { shift = 7, mask = 1, [0] = map_misc, map_mulh, },
374 _ = { 373 _ = {
375 shift = 0, mask = 0xffffffff, 374 shift = 0, mask = 0xffffffff,
376 [bor(0xe1a00000)] = "nop", 375 [0xe1a00000|0] = "nop",
377 _ = map_data, 376 _ = map_data,
378 } 377 }
379 }, 378 },
@@ -427,7 +426,7 @@ local function putop(ctx, text, operands)
427 local sym = ctx.symtab[ctx.rel] 426 local sym = ctx.symtab[ctx.rel]
428 if sym then 427 if sym then
429 extra = "\t->"..sym 428 extra = "\t->"..sym
430 elseif band(ctx.op, 0x0e000000) ~= 0x0a000000 then 429 elseif ctx.op & 0x0e000000 != 0x0a000000 then
431 extra = "\t; 0x"..tohex(ctx.rel) 430 extra = "\t; 0x"..tohex(ctx.rel)
432 end 431 end
433 end 432 end
@@ -448,47 +447,47 @@ end
448 447
449-- Format operand 2 of load/store opcodes. 448-- Format operand 2 of load/store opcodes.
450local function fmtload(ctx, op, pos) 449local function fmtload(ctx, op, pos)
451 local base = map_gpr[band(rshift(op, 16), 15)] 450 local base = map_gpr[(op >> 16) & 15]
452 local x, ofs 451 local x, ofs
453 local ext = (band(op, 0x04000000) == 0) 452 local ext = (op & 0x04000000 == 0)
454 if not ext and band(op, 0x02000000) == 0 then 453 if not ext and op & 0x02000000 == 0 then
455 ofs = band(op, 4095) 454 ofs = op & 4095
456 if band(op, 0x00800000) == 0 then ofs = -ofs end 455 if op & 0x00800000 == 0 then ofs = -ofs end
457 if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end 456 if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
458 ofs = "#"..ofs 457 ofs = "#"..ofs
459 elseif ext and band(op, 0x00400000) ~= 0 then 458 elseif ext and op & 0x00400000 != 0 then
460 ofs = band(op, 15) + band(rshift(op, 4), 0xf0) 459 ofs = (op & 0x0f) | ((op >> 4) & 0xf0)
461 if band(op, 0x00800000) == 0 then ofs = -ofs end 460 if op & 0x00800000 == 0 then ofs = -ofs end
462 if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end 461 if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
463 ofs = "#"..ofs 462 ofs = "#"..ofs
464 else 463 else
465 ofs = map_gpr[band(op, 15)] 464 ofs = map_gpr[op & 15]
466 if ext or band(op, 0xfe0) == 0 then 465 if ext or op & 0xfe0 == 0 then
467 elseif band(op, 0xfe0) == 0x60 then 466 elseif op & 0xfe0 == 0x60 then
468 ofs = format("%s, rrx", ofs) 467 ofs = format("%s, rrx", ofs)
469 else 468 else
470 local sh = band(rshift(op, 7), 31) 469 local sh = (op >> 7) & 31
471 if sh == 0 then sh = 32 end 470 if sh == 0 then sh = 32 end
472 ofs = format("%s, %s #%d", ofs, map_shift[band(rshift(op, 5), 3)], sh) 471 ofs = format("%s, %s #%d", ofs, map_shift[(op >> 5) & 3], sh)
473 end 472 end
474 if band(op, 0x00800000) == 0 then ofs = "-"..ofs end 473 if op & 0x00800000 == 0 then ofs = "-"..ofs end
475 end 474 end
476 if ofs == "#0" then 475 if ofs == "#0" then
477 x = format("[%s]", base) 476 x = format("[%s]", base)
478 elseif band(op, 0x01000000) == 0 then 477 elseif op & 0x01000000 == 0 then
479 x = format("[%s], %s", base, ofs) 478 x = format("[%s], %s", base, ofs)
480 else 479 else
481 x = format("[%s, %s]", base, ofs) 480 x = format("[%s, %s]", base, ofs)
482 end 481 end
483 if band(op, 0x01200000) == 0x01200000 then x = x.."!" end 482 if op & 0x01200000 == 0x01200000 then x ..= "!" end
484 return x 483 return x
485end 484end
486 485
487-- Format operand 2 of vector load/store opcodes. 486-- Format operand 2 of vector load/store opcodes.
488local function fmtvload(ctx, op, pos) 487local function fmtvload(ctx, op, pos)
489 local base = map_gpr[band(rshift(op, 16), 15)] 488 local base = map_gpr[(op >> 16) & 15]
490 local ofs = band(op, 255)*4 489 local ofs = (op & 255) << 2
491 if band(op, 0x00800000) == 0 then ofs = -ofs end 490 if op & 0x00800000 == 0 then ofs = -ofs end
492 if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end 491 if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
493 if ofs == 0 then 492 if ofs == 0 then
494 return format("[%s]", base) 493 return format("[%s]", base)
@@ -499,9 +498,9 @@ end
499 498
500local function fmtvr(op, vr, sh0, sh1) 499local function fmtvr(op, vr, sh0, sh1)
501 if vr == "s" then 500 if vr == "s" then
502 return format("s%d", 2*band(rshift(op, sh0), 15)+band(rshift(op, sh1), 1)) 501 return format("s%d", ((op >> sh0-1) & 0x1e) | ((op >> sh1) & 1))
503 else 502 else
504 return format("d%d", band(rshift(op, sh0), 15)+band(rshift(op, sh1-4), 16)) 503 return format("d%d", ((op >> sh0) & 15) | ((op >> sh1-4) & 16))
505 end 504 end
506end 505end
507 506
@@ -509,7 +508,7 @@ end
509local function disass_ins(ctx) 508local function disass_ins(ctx)
510 local pos = ctx.pos 509 local pos = ctx.pos
511 local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) 510 local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
512 local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0) 511 local op = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0
513 local operands = {} 512 local operands = {}
514 local suffix = "" 513 local suffix = ""
515 local last, name, pat 514 local last, name, pat
@@ -517,35 +516,35 @@ local function disass_ins(ctx)
517 ctx.op = op 516 ctx.op = op
518 ctx.rel = nil 517 ctx.rel = nil
519 518
520 local cond = rshift(op, 28) 519 local cond = op >> 28
521 local opat 520 local opat
522 if cond == 15 then 521 if cond == 15 then
523 opat = map_uncondins[band(rshift(op, 25), 7)] 522 opat = map_uncondins[(op >> 25) & 7]
524 else 523 else
525 if cond ~= 14 then suffix = map_cond[cond] end 524 if cond != 14 then suffix = map_cond[cond] end
526 opat = map_condins[band(rshift(op, 25), 7)] 525 opat = map_condins[(op >> 25) & 7]
527 end 526 end
528 while type(opat) ~= "string" do 527 while type(opat) != "string" do
529 if not opat then return unknown(ctx) end 528 if not opat then return unknown(ctx) end
530 opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ 529 opat = opat[(op >> opat.shift) & opat.mask] or opat._
531 end 530 end
532 name, pat = match(opat, "^([a-z0-9]*)(.*)") 531 name, pat = match(opat, "^([a-z0-9]*)(.*)")
533 if sub(pat, 1, 1) == "." then 532 if sub(pat, 1, 1) == "." then
534 local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)") 533 local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)")
535 suffix = suffix..s2 534 suffix ..= s2
536 pat = p2 535 pat = p2
537 end 536 end
538 537
539 for p in gmatch(pat, ".") do 538 for p in gmatch(pat, ".") do
540 local x = nil 539 local x = nil
541 if p == "D" then 540 if p == "D" then
542 x = map_gpr[band(rshift(op, 12), 15)] 541 x = map_gpr[(op >> 12) & 15]
543 elseif p == "N" then 542 elseif p == "N" then
544 x = map_gpr[band(rshift(op, 16), 15)] 543 x = map_gpr[(op >> 16) & 15]
545 elseif p == "S" then 544 elseif p == "S" then
546 x = map_gpr[band(rshift(op, 8), 15)] 545 x = map_gpr[(op >> 8) & 15]
547 elseif p == "M" then 546 elseif p == "M" then
548 x = map_gpr[band(op, 15)] 547 x = map_gpr[op & 15]
549 elseif p == "d" then 548 elseif p == "d" then
550 x = fmtvr(op, vr, 12, 22) 549 x = fmtvr(op, vr, 12, 22)
551 elseif p == "n" then 550 elseif p == "n" then
@@ -553,20 +552,20 @@ local function disass_ins(ctx)
553 elseif p == "m" then 552 elseif p == "m" then
554 x = fmtvr(op, vr, 0, 5) 553 x = fmtvr(op, vr, 0, 5)
555 elseif p == "P" then 554 elseif p == "P" then
556 if band(op, 0x02000000) ~= 0 then 555 if op & 0x02000000 != 0 then
557 x = ror(band(op, 255), 2*band(rshift(op, 8), 15)) 556 x = ror(op & 0xff, (op >> 7) & 0x1e)
558 else 557 else
559 x = map_gpr[band(op, 15)] 558 x = map_gpr[op & 15]
560 if band(op, 0xff0) ~= 0 then 559 if op & 0xff0 != 0 then
561 operands[#operands+1] = x 560 operands[#operands+1] = x
562 local s = map_shift[band(rshift(op, 5), 3)] 561 local s = map_shift[(op >> 5) & 3]
563 local r = nil 562 local r = nil
564 if band(op, 0xf90) == 0 then 563 if op & 0xf90 == 0 then
565 if s == "ror" then s = "rrx" else r = "#32" end 564 if s == "ror" then s = "rrx" else r = "#32" end
566 elseif band(op, 0x10) == 0 then 565 elseif op & 0x10 == 0 then
567 r = "#"..band(rshift(op, 7), 31) 566 r = "#"..((op >> 7) & 31)
568 else 567 else
569 r = map_gpr[band(rshift(op, 8), 15)] 568 r = map_gpr[(op >> 8) & 15]
570 end 569 end
571 if name == "mov" then name = s; x = r 570 if name == "mov" then name = s; x = r
572 elseif r then x = format("%s %s", s, r) 571 elseif r then x = format("%s %s", s, r)
@@ -578,8 +577,8 @@ local function disass_ins(ctx)
578 elseif p == "l" then 577 elseif p == "l" then
579 x = fmtvload(ctx, op, pos) 578 x = fmtvload(ctx, op, pos)
580 elseif p == "B" then 579 elseif p == "B" then
581 local addr = ctx.addr + pos + 8 + arshift(lshift(op, 8), 6) 580 local addr = ctx.addr + pos + 8 + ((op << 8) ~>> 6)
582 if cond == 15 then addr = addr + band(rshift(op, 23), 2) end 581 if cond == 15 then addr += (op >> 23) & 2 end
583 ctx.rel = addr 582 ctx.rel = addr
584 x = "0x"..tohex(addr) 583 x = "0x"..tohex(addr)
585 elseif p == "F" then 584 elseif p == "F" then
@@ -587,52 +586,52 @@ local function disass_ins(ctx)
587 elseif p == "G" then 586 elseif p == "G" then
588 vr = "d" 587 vr = "d"
589 elseif p == "." then 588 elseif p == "." then
590 suffix = suffix..(vr == "s" and ".f32" or ".f64") 589 suffix ..= vr == "s" ? ".f32" : ".f64"
591 elseif p == "R" then 590 elseif p == "R" then
592 if band(op, 0x00200000) ~= 0 and #operands == 1 then 591 if op & 0x00200000 != 0 and #operands == 1 then
593 operands[1] = operands[1].."!" 592 operands[1] = operands[1].."!"
594 end 593 end
595 local t = {} 594 local t = {}
596 for i=0,15 do 595 for i=0,15 do
597 if band(rshift(op, i), 1) == 1 then t[#t+1] = map_gpr[i] end 596 if (op >> i) & 1 == 1 then t[#t+1] = map_gpr[i] end
598 end 597 end
599 x = "{"..concat(t, ", ").."}" 598 x = "{"..concat(t, ", ").."}"
600 elseif p == "r" then 599 elseif p == "r" then
601 if band(op, 0x00200000) ~= 0 and #operands == 2 then 600 if op & 0x00200000 != 0 and #operands == 2 then
602 operands[1] = operands[1].."!" 601 operands[1] = operands[1].."!"
603 end 602 end
604 local s = tonumber(sub(last, 2)) 603 local s = tonumber(sub(last, 2))
605 local n = band(op, 255) 604 local n = op & 0xff
606 if vr == "d" then n = rshift(n, 1) end 605 if vr == "d" then n >>= 1 end
607 operands[#operands] = format("{%s-%s%d}", last, vr, s+n-1) 606 operands[#operands] = format("{%s-%s%d}", last, vr, s+n-1)
608 elseif p == "W" then 607 elseif p == "W" then
609 x = band(op, 0x0fff) + band(rshift(op, 4), 0xf000) 608 x = (op & 0x0fff) | ((op >> 4) & 0xf000)
610 elseif p == "T" then 609 elseif p == "T" then
611 x = "#0x"..tohex(band(op, 0x00ffffff), 6) 610 x = "#0x"..tohex(op & 0x00ffffff, 6)
612 elseif p == "U" then 611 elseif p == "U" then
613 x = band(rshift(op, 7), 31) 612 x = (op >> 7) & 31
614 if x == 0 then x = nil end 613 if x == 0 then x = nil end
615 elseif p == "u" then 614 elseif p == "u" then
616 x = band(rshift(op, 7), 31) 615 x = (op >> 7) & 31
617 if band(op, 0x40) == 0 then 616 if op & 0x40 == 0 then
618 if x == 0 then x = nil else x = "lsl #"..x end 617 x = x == 0 ? nil : "lsl #"..x
619 else 618 else
620 if x == 0 then x = "asr #32" else x = "asr #"..x end 619 x = x == 0 ? "asr #32" : "asr #"..x
621 end 620 end
622 elseif p == "v" then 621 elseif p == "v" then
623 x = band(rshift(op, 7), 31) 622 x = (op >> 7) & 31
624 elseif p == "w" then 623 elseif p == "w" then
625 x = band(rshift(op, 16), 31) 624 x = (op >> 16) & 31
626 elseif p == "x" then 625 elseif p == "x" then
627 x = band(rshift(op, 16), 31) + 1 626 x = ((op >> 16) & 31) + 1
628 elseif p == "X" then 627 elseif p == "X" then
629 x = band(rshift(op, 16), 31) - last + 1 628 x = ((op >> 16) & 31) - last + 1
630 elseif p == "Y" then 629 elseif p == "Y" then
631 x = band(rshift(op, 12), 0xf0) + band(op, 0x0f) 630 x = ((op >> 12) & 0xf0) | (op & 0x0f)
632 elseif p == "K" then 631 elseif p == "K" then
633 x = "#0x"..tohex(band(rshift(op, 4), 0x0000fff0) + band(op, 15), 4) 632 x = "#0x"..tohex(((op >> 4) & 0xfff0) | (op & 0x000f), 4)
634 elseif p == "s" then 633 elseif p == "s" then
635 if band(op, 0x00100000) ~= 0 then suffix = "s"..suffix end 634 if op & 0x00100000 != 0 then suffix = "s"..suffix end
636 else 635 else
637 assert(false) 636 assert(false)
638 end 637 end
@@ -651,7 +650,7 @@ end
651-- Disassemble a block of code. 650-- Disassemble a block of code.
652local function disass_block(ctx, ofs, len) 651local function disass_block(ctx, ofs, len)
653 if not ofs then ofs = 0 end 652 if not ofs then ofs = 0 end
654 local stop = len and ofs+len or #ctx.code 653 local stop = len ? ofs+len : #ctx.code
655 ctx.pos = ofs 654 ctx.pos = ofs
656 ctx.rel = nil 655 ctx.rel = nil
657 while ctx.pos < stop do disass_ins(ctx) end 656 while ctx.pos < stop do disass_ins(ctx) end