summaryrefslogtreecommitdiff
path: root/src/jit
diff options
context:
space:
mode:
authorMike Pall <mike>2012-07-29 12:17:13 +0200
committerMike Pall <mike>2012-07-29 12:17:13 +0200
commitb98c1582c9129e7db59e4edaf7236671b36b523c (patch)
tree849a8d0fa91148b9fbe15d2a867f9ed9fbc72812 /src/jit
parent2d58872cb5ce72bb99ec5a8ed941cc3a7930a95c (diff)
downloadluajit-b98c1582c9129e7db59e4edaf7236671b36b523c.tar.gz
luajit-b98c1582c9129e7db59e4edaf7236671b36b523c.tar.bz2
luajit-b98c1582c9129e7db59e4edaf7236671b36b523c.zip
ARM: Add VFP instructions to ARM disassembler.
Diffstat (limited to 'src/jit')
-rw-r--r--src/jit/dis_arm.lua163
1 files changed, 154 insertions, 9 deletions
diff --git a/src/jit/dis_arm.lua b/src/jit/dis_arm.lua
index 0fcd1bed..ecca392f 100644
--- a/src/jit/dis_arm.lua
+++ b/src/jit/dis_arm.lua
@@ -23,24 +23,118 @@ local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
23------------------------------------------------------------------------------ 23------------------------------------------------------------------------------
24 24
25local map_loadc = { 25local map_loadc = {
26 shift = 9, mask = 7, 26 shift = 8, mask = 15,
27 [5] = { 27 [10] = {
28 shift = 0, mask = 0 -- NYI VFP load/store. 28 shift = 20, mask = 1,
29 [0] = {
30 shift = 23, mask = 3,
31 [0] = "vmovFmDN", "vstmFNdr",
32 _ = {
33 shift = 21, mask = 1,
34 [0] = "vstrFdl",
35 { shift = 16, mask = 15, [13] = "vpushFdr", _ = "vstmdbFNdr", }
36 },
37 },
38 {
39 shift = 23, mask = 3,
40 [0] = "vmovFDNm",
41 { shift = 16, mask = 15, [13] = "vpopFdr", _ = "vldmFNdr", },
42 _ = {
43 shift = 21, mask = 1,
44 [0] = "vldrFdl", "vldmdbFNdr",
45 },
46 },
47 },
48 [11] = {
49 shift = 20, mask = 1,
50 [0] = {
51 shift = 23, mask = 3,
52 [0] = "vmovGmDN", "vstmGNdr",
53 _ = {
54 shift = 21, mask = 1,
55 [0] = "vstrGdl",
56 { shift = 16, mask = 15, [13] = "vpushGdr", _ = "vstmdbGNdr", }
57 },
58 },
59 {
60 shift = 23, mask = 3,
61 [0] = "vmovGDNm",
62 { shift = 16, mask = 15, [13] = "vpopGdr", _ = "vldmGNdr", },
63 _ = {
64 shift = 21, mask = 1,
65 [0] = "vldrGdl", "vldmdbGNdr",
66 },
67 },
29 }, 68 },
30 _ = { 69 _ = {
31 shift = 0, mask = 0 -- NYI ldc, mcrr, mrrc. 70 shift = 0, mask = 0 -- NYI ldc, mcrr, mrrc.
32 }, 71 },
33} 72}
34 73
74local map_vfps = {
75 shift = 6, mask = 0x2c001,
76 [0] = "vmlaF.dnm", "vmlsF.dnm",
77 [0x04000] = "vnmlsF.dnm", [0x04001] = "vnmlaF.dnm",
78 [0x08000] = "vmulF.dnm", [0x08001] = "vnmulF.dnm",
79 [0x0c000] = "vaddF.dnm", [0x0c001] = "vsubF.dnm",
80 [0x20000] = "vdivF.dnm",
81 [0x24000] = "vfnmsF.dnm", [0x24001] = "vfnmaF.dnm",
82 [0x28000] = "vfmaF.dnm", [0x28001] = "vfmsF.dnm",
83 [0x2c000] = "vmovF.dY",
84 [0x2c001] = {
85 shift = 7, mask = 0x1e01,
86 [0] = "vmovF.dm", "vabsF.dm",
87 [0x0200] = "vnegF.dm", [0x0201] = "vsqrtF.dm",
88 [0x0800] = "vcmpF.dm", [0x0801] = "vcmpeF.dm",
89 [0x0a00] = "vcmpzF.d", [0x0a01] = "vcmpzeF.d",
90 [0x0e01] = "vcvtG.dF.m",
91 [0x1000] = "vcvt.f32.u32Fdm", [0x1001] = "vcvt.f32.s32Fdm",
92 [0x1800] = "vcvtr.u32F.dm", [0x1801] = "vcvt.u32F.dm",
93 [0x1a00] = "vcvtr.s32F.dm", [0x1a01] = "vcvt.s32F.dm",
94 },
95}
96
97local map_vfpd = {
98 shift = 6, mask = 0x2c001,
99 [0] = "vmlaG.dnm", "vmlsG.dnm",
100 [0x04000] = "vnmlsG.dnm", [0x04001] = "vnmlaG.dnm",
101 [0x08000] = "vmulG.dnm", [0x08001] = "vnmulG.dnm",
102 [0x0c000] = "vaddG.dnm", [0x0c001] = "vsubG.dnm",
103 [0x20000] = "vdivG.dnm",
104 [0x24000] = "vfnmsG.dnm", [0x24001] = "vfnmaG.dnm",
105 [0x28000] = "vfmaG.dnm", [0x28001] = "vfmsG.dnm",
106 [0x2c000] = "vmovG.dY",
107 [0x2c001] = {
108 shift = 7, mask = 0x1e01,
109 [0] = "vmovG.dm", "vabsG.dm",
110 [0x0200] = "vnegG.dm", [0x0201] = "vsqrtG.dm",
111 [0x0800] = "vcmpG.dm", [0x0801] = "vcmpeG.dm",
112 [0x0a00] = "vcmpzG.d", [0x0a01] = "vcmpzeG.d",
113 [0x0e01] = "vcvtF.dG.m",
114 [0x1000] = "vcvt.f64.u32GdFm", [0x1001] = "vcvt.f64.s32GdFm",
115 [0x1800] = "vcvtr.u32FdG.m", [0x1801] = "vcvt.u32FdG.m",
116 [0x1a00] = "vcvtr.s32FdG.m", [0x1a01] = "vcvt.s32FdG.m",
117 },
118}
119
35local map_datac = { 120local map_datac = {
36 shift = 24, mask = 1, 121 shift = 24, mask = 1,
37 [0] = { 122 [0] = {
38 shift = 9, mask = 7, 123 shift = 4, mask = 1,
39 [5] = { 124 [0] = {
40 shift = 0, mask = 0 -- NYI VFP data. 125 shift = 8, mask = 15,
126 [10] = map_vfps,
127 [11] = map_vfpd,
128 -- NYI cdp, mcr, mrc.
41 }, 129 },
42 _ = { 130 {
43 shift = 0, mask = 0 -- NYI cdp, mcr, mrc. 131 shift = 8, mask = 15,
132 [10] = {
133 shift = 20, mask = 15,
134 [0] = "vmovFnD", "vmovFDn",
135 [14] = "vmsrD",
136 [15] = { shift = 12, mask = 15, [15] = "vmrs", _ = "vmrsD", },
137 },
44 }, 138 },
45 }, 139 },
46 "svcT", 140 "svcT",
@@ -390,6 +484,27 @@ local function fmtload(ctx, op, pos)
390 return x 484 return x
391end 485end
392 486
487-- Format operand 2 of vector load/store opcodes.
488local function fmtvload(ctx, op, pos)
489 local base = map_gpr[band(rshift(op, 16), 15)]
490 local ofs = band(op, 255)*4
491 if band(op, 0x00800000) == 0 then ofs = -ofs end
492 if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
493 if ofs == 0 then
494 return format("[%s]", base)
495 else
496 return format("[%s, #%d]", base, ofs)
497 end
498end
499
500local function fmtvr(op, vr, sh0, sh1)
501 if vr == "s" then
502 return format("s%d", 2*band(rshift(op, sh0), 15)+band(rshift(op, sh1), 1))
503 else
504 return format("d%d", band(rshift(op, sh0), 15)+band(rshift(op, sh1-4), 16))
505 end
506end
507
393-- Disassemble a single instruction. 508-- Disassemble a single instruction.
394local function disass_ins(ctx) 509local function disass_ins(ctx)
395 local pos = ctx.pos 510 local pos = ctx.pos
@@ -398,6 +513,7 @@ local function disass_ins(ctx)
398 local operands = {} 513 local operands = {}
399 local suffix = "" 514 local suffix = ""
400 local last, name, pat 515 local last, name, pat
516 local vr
401 ctx.op = op 517 ctx.op = op
402 ctx.rel = nil 518 ctx.rel = nil
403 519
@@ -414,6 +530,11 @@ local function disass_ins(ctx)
414 opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ 530 opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._
415 end 531 end
416 name, pat = match(opat, "^([a-z0-9]*)(.*)") 532 name, pat = match(opat, "^([a-z0-9]*)(.*)")
533 if sub(pat, 1, 1) == "." then
534 local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)")
535 suffix = suffix..s2
536 pat = p2
537 end
417 538
418 for p in gmatch(pat, ".") do 539 for p in gmatch(pat, ".") do
419 local x = nil 540 local x = nil
@@ -425,6 +546,12 @@ local function disass_ins(ctx)
425 x = map_gpr[band(rshift(op, 8), 15)] 546 x = map_gpr[band(rshift(op, 8), 15)]
426 elseif p == "M" then 547 elseif p == "M" then
427 x = map_gpr[band(op, 15)] 548 x = map_gpr[band(op, 15)]
549 elseif p == "d" then
550 x = fmtvr(op, vr, 12, 22)
551 elseif p == "n" then
552 x = fmtvr(op, vr, 16, 7)
553 elseif p == "m" then
554 x = fmtvr(op, vr, 0, 5)
428 elseif p == "P" then 555 elseif p == "P" then
429 if band(op, 0x02000000) ~= 0 then 556 if band(op, 0x02000000) ~= 0 then
430 x = ror(band(op, 255), 2*band(rshift(op, 8), 15)) 557 x = ror(band(op, 255), 2*band(rshift(op, 8), 15))
@@ -447,12 +574,20 @@ local function disass_ins(ctx)
447 end 574 end
448 end 575 end
449 elseif p == "L" then 576 elseif p == "L" then
450 x = fmtload(ctx, op, pos, false) 577 x = fmtload(ctx, op, pos)
578 elseif p == "l" then
579 x = fmtvload(ctx, op, pos)
451 elseif p == "B" then 580 elseif p == "B" then
452 local addr = ctx.addr + pos + 8 + arshift(lshift(op, 8), 6) 581 local addr = ctx.addr + pos + 8 + arshift(lshift(op, 8), 6)
453 if cond == 15 then addr = addr + band(rshift(op, 23), 2) end 582 if cond == 15 then addr = addr + band(rshift(op, 23), 2) end
454 ctx.rel = addr 583 ctx.rel = addr
455 x = "0x"..tohex(addr) 584 x = "0x"..tohex(addr)
585 elseif p == "F" then
586 vr = "s"
587 elseif p == "G" then
588 vr = "d"
589 elseif p == "." then
590 suffix = suffix..(vr == "s" and ".f32" or ".f64")
456 elseif p == "R" then 591 elseif p == "R" then
457 if band(op, 0x00200000) ~= 0 and #operands == 1 then 592 if band(op, 0x00200000) ~= 0 and #operands == 1 then
458 operands[1] = operands[1].."!" 593 operands[1] = operands[1].."!"
@@ -462,6 +597,14 @@ local function disass_ins(ctx)
462 if band(rshift(op, i), 1) == 1 then t[#t+1] = map_gpr[i] end 597 if band(rshift(op, i), 1) == 1 then t[#t+1] = map_gpr[i] end
463 end 598 end
464 x = "{"..concat(t, ", ").."}" 599 x = "{"..concat(t, ", ").."}"
600 elseif p == "r" then
601 if band(op, 0x00200000) ~= 0 and #operands == 2 then
602 operands[1] = operands[1].."!"
603 end
604 local s = tonumber(sub(last, 2))
605 local n = band(op, 255)
606 if vr == "d" then n = rshift(n, 1) end
607 operands[#operands] = format("{%s-%s%d}", last, vr, s+n-1)
465 elseif p == "W" then 608 elseif p == "W" then
466 x = band(op, 0x0fff) + band(rshift(op, 4), 0xf000) 609 x = band(op, 0x0fff) + band(rshift(op, 4), 0xf000)
467 elseif p == "T" then 610 elseif p == "T" then
@@ -484,6 +627,8 @@ local function disass_ins(ctx)
484 x = band(rshift(op, 16), 31) + 1 627 x = band(rshift(op, 16), 31) + 1
485 elseif p == "X" then 628 elseif p == "X" then
486 x = band(rshift(op, 16), 31) - last + 1 629 x = band(rshift(op, 16), 31) - last + 1
630 elseif p == "Y" then
631 x = band(rshift(op, 12), 0xf0) + band(op, 0x0f)
487 elseif p == "K" then 632 elseif p == "K" then
488 x = "#0x"..tohex(band(rshift(op, 4), 0x0000fff0) + band(op, 15), 4) 633 x = "#0x"..tohex(band(rshift(op, 4), 0x0000fff0) + band(op, 15), 4)
489 elseif p == "s" then 634 elseif p == "s" then