envydis: Add PVCOMP microcode disassembler

This commit is contained in:
Marcin Kościelnicki
2013-08-15 18:29:06 +02:00
parent ce94594bb5
commit 40e4b02579
6 changed files with 200 additions and 2 deletions

View File

@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.6)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
add_library(envy core.c core-as.c core-dis.c nv50.c nvc0.c gk110.c ctx.c fuc.c hwsq.c vp2.c vuc.c macro.c vp1.c)
add_library(envy core.c core-as.c core-dis.c nv50.c nvc0.c gk110.c ctx.c fuc.c hwsq.c vp2.c vuc.c macro.c vp1.c vcomp.c)
add_executable(envydis envydis.c)
add_executable(envyas envyas.c)

View File

@ -26,6 +26,7 @@ hexadecimal numbers representing the bytes to disassemble. The options are:
[*** ] vuc: video processor 2/3 master/mocomp microcode
[****] macro: nvc0 PGRAPH macro method ISA
[** ] vp1: video processor 1 [nv41-gen] code
[****] vcomp: PVCOMP video compositor microcode
Where the quality level is:
[ ]: Bare beginnings
[* ]: Knows a few instructions

View File

@ -48,6 +48,7 @@ static const struct {
"vµc", &vuc_isa_s,
"macro", &macro_isa_s,
"vp1", &vp1_isa_s,
"vcomp", &vcomp_isa_s,
};
const struct disisa *ed_getisa(const char *name) {

View File

@ -310,5 +310,6 @@ extern struct disisa vp2_isa_s;
extern struct disisa vuc_isa_s;
extern struct disisa macro_isa_s;
extern struct disisa vp1_isa_s;
extern struct disisa vcomp_isa_s;
#endif

195
envydis/vcomp.c Normal file
View File

@ -0,0 +1,195 @@
/*
* Copyright (C) 2013 Marcin Kościelnicki <koriakin@0x04.net>
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "dis-intern.h"
static struct rbitfield ctargoff = { 8, 6, 17, 2 };
#define BTARG atombtarg, &ctargoff
#define CTARG atomctarg, &ctargoff
static struct rbitfield limmoff = { 8, 6, 17, 6 };
static struct rbitfield immoff = { 17, 6 };
#define LIMM atomimm, &limmoff
#define IMM atomimm, &immoff
static struct bitfield src1_bf = { 8, 3 };
static struct bitfield src2_bf = { 11, 3 };
static struct bitfield dst_bf = { 14, 3 };
static struct bitfield psrc1_bf = { 8, 2 };
static struct bitfield psrc2_bf = { 11, 2 };
static struct bitfield pdst_bf = { 14, 2 };
static struct reg src1_r = { &src1_bf, "r" };
static struct reg src2_r = { &src2_bf, "r" };
static struct reg dst_r = { &dst_bf, "r" };
static struct reg memidx_r = { 0, "memidx" };
static struct reg ififo_r = { 0, "ififo" };
#define SRC1 atomreg, &src1_r
#define SRC2 atomreg, &src2_r
#define DST atomreg, &dst_r
#define MEMIDX atomreg, &memidx_r
#define IFIFO atomreg, &ififo_r
static struct sreg pred_sr[] = {
{ 3, "irq" },
{ -1 },
};
static struct reg psrc1_r = { &psrc1_bf, "p", .specials = pred_sr };
static struct reg psrc2_r = { &psrc2_bf, "p", .specials = pred_sr };
static struct reg pdst_r = { &pdst_bf, "p", .specials = pred_sr };
static struct reg pred_r = { 0, "p0" };
#define PSRC1 atomreg, &psrc1_r
#define PSRC2 atomreg, &psrc2_r
#define PDST atomreg, &pdst_r
#define PRED atomreg, &pred_r
static struct rbitfield memoff = { 17, 6 };
static struct mem mem0_m = { "M0", 0, &memidx_r };
static struct mem mem1_m = { "M1", 0, &memidx_r };
static struct mem mem2_m = { "M2", 0, &memidx_r };
static struct mem mem3_m = { "M3", 0, &memidx_r };
static struct mem datar_m = { "D", 0, &src2_r };
static struct mem datai_m = { "D", 0, 0, &memoff };
static struct mem outr_m = { "O", 0, &src2_r };
static struct mem outi_m = { "O", 0, 0, &memoff };
#define MEM0 atommem, &mem0_m
#define MEM1 atommem, &mem1_m
#define MEM2 atommem, &mem2_m
#define MEM3 atommem, &mem3_m
#define DATAR atommem, &datar_m
#define DATAI atommem, &datai_m
#define OUTR atommem, &outr_m
#define OUTI atommem, &outi_m
static struct insn tabpdst[] = {
{ 0x000000, 0x010000, PDST },
{ 0x010000, 0x010000, N("not"), PDST },
{ 0, 0, OOPS },
};
static struct insn tabpsrc1[] = {
{ 0x000000, 0x000400, PSRC1 },
{ 0x000400, 0x000400, N("not"), PSRC1 },
{ 0, 0, OOPS },
};
static struct insn tabpsrc2[] = {
{ 0x000000, 0x002000, PSRC2 },
{ 0x002000, 0x002000, N("not"), PSRC2 },
{ 0, 0, OOPS },
};
static struct insn tabsrc2[] = {
{ 0x000000, 0x000040, SRC2 },
{ 0x000040, 0x000040, IMM },
{ 0, 0, OOPS },
};
static struct insn tablsrc2[] = {
{ 0x000000, 0x000040, SRC2 },
{ 0x000040, 0x000040, LIMM },
{ 0, 0, OOPS },
};
static int ignimm[] = { 6, 1 };
#define IGNIMM atomign, ignimm
static struct insn tabpred[] = {
{ 0x000000, 0x000080 },
{ 0x000080, 0x000080, PRED },
{ 0, 0, OOPS },
};
static struct insn tabldmem[] = {
{ 0x000000, 0x000700, IGNIMM, MEM0 },
{ 0x000100, 0x000700, IGNIMM, MEM1 },
{ 0x000200, 0x000700, IGNIMM, MEM2 },
{ 0x000300, 0x000700, IGNIMM, MEM3 },
{ 0x000400, 0x000740, DATAR },
{ 0x000440, 0x000740, DATAI },
{ 0x000600, 0x000700, IGNIMM, MEMIDX },
{ 0x000700, 0x000700, IGNIMM, IFIFO },
{ 0, 0, OOPS },
};
static struct insn tabstmem[] = {
{ 0x000000, 0x01c000, IGNIMM, MEM0 },
{ 0x004000, 0x01c000, IGNIMM, MEM1 },
{ 0x008000, 0x01c000, IGNIMM, MEM2 },
{ 0x00c000, 0x01c000, IGNIMM, MEM3 },
{ 0x010000, 0x01c040, DATAR },
{ 0x010040, 0x01c040, DATAI },
{ 0x014000, 0x01c040, OUTR },
{ 0x014040, 0x01c040, OUTI },
{ 0x018000, 0x01c000, IGNIMM, MEMIDX },
{ 0, 0, OOPS },
};
static struct insn tabm[] = {
{ 0x000000, 0x00003f, T(pred), N("add"), DST, SRC1, T(src2) },
{ 0x000001, 0x00003f, T(pred), N("sub"), DST, SRC1, T(src2) },
{ 0x000002, 0x00003f, T(pred), N("sar"), DST, SRC1, T(src2) }, /* only low 6 bits of SRC2 used */
{ 0x000003, 0x00003f, T(pred), N("shl"), DST, SRC1, T(src2) }, /* only low 6 bits of SRC2 used */
{ 0x000004, 0x00003f, T(pred), N("and"), DST, SRC1, T(src2) },
{ 0x000005, 0x00003f, T(pred), N("or"), DST, SRC1, T(src2) },
{ 0x000006, 0x00003f, T(pred), N("xor"), DST, SRC1, T(src2) },
{ 0x000007, 0x00003f, T(pred), N("not"), DST, SRC1 },
{ 0x000008, 0x00003f, T(pred), N("mov"), DST, T(lsrc2) },
{ 0x000009, 0x00003f, T(pred), N("hswap"), DST, SRC1 }, /* swap bits 0-15 with 16-31 ... */
{ 0x00000a, 0x00003f, T(pred), N("min"), DST, SRC1, T(src2) },
{ 0x00000b, 0x00003f, T(pred), N("max"), DST, SRC1, T(src2) },
{ 0x00000c, 0x00003f, T(pred), N("setgt"), T(pdst), SRC1, T(src2) },
{ 0x00000d, 0x00003f, T(pred), N("setlt"), T(pdst), SRC1, T(src2) },
{ 0x00000e, 0x00003f, T(pred), N("seteq"), T(pdst), SRC1, T(src2) },
{ 0x00000f, 0x00003f, T(pred), N("btest"), T(pdst), SRC1, T(src2) },
{ 0x000010, 0x00003f, T(pred), N("and"), T(pdst), T(psrc1), T(psrc2) },
{ 0x000011, 0x00003f, T(pred), N("or"), T(pdst), T(psrc1), T(psrc2) },
{ 0x000012, 0x00003f, T(pred), N("xor"), T(pdst), T(psrc1), T(psrc2) },
{ 0x000013, 0x00003f, T(pred), N("mov"), T(pdst), T(psrc1) },
{ 0x000014, 0x00003f, T(pred), N("set"), T(pdst) }, /* set to 1... */
{ 0x000015, 0x00003f, T(pred), N("exp2"), DST, T(src2) }, /* DST = 1 << (SRC2 & 0x3f) */
{ 0x000016, 0x00003f, T(pred), N("exp2m1"), DST, T(src2) }, /* DST = 1 << ((SRC2 & 0x3f)) - 1 */
{ 0x000020, 0x00003f, N("ldu"), DST, T(ldmem) },
{ 0x000021, 0x00003f, N("lds"), DST, T(ldmem) },
{ 0x000022, 0x00003f, N("st"), T(stmem), SRC1 },
{ 0x000024, 0x00003f, N("div"), DST, SRC1, T(src2) }, /* s48 by u16 -> s48, -1 on div-by-0 */
{ 0x000025, 0x00003f, IGNIMM, N("mulsrr"), DST, SRC1, SRC2, IMM }, /* s48 by s16, then shift + round up */
{ 0x000026, 0x00003f, IGNIMM, N("sleep") },
{ 0x000028, 0x00003f, IGNIMM, N("bra"), BTARG },
{ 0x00002a, 0x00003f, IGNIMM, SESTART, N("not"), PDST, SEEND, N("bra"), BTARG },
{ 0x00002b, 0x00003f, IGNIMM, PDST, N("bra"), BTARG },
{ 0x00002c, 0x00003f, IGNIMM, N("bra"), BTARG }, /* XXX wtf? */
{ 0x00002e, 0x00003f, IGNIMM, N("call"), CTARG },
{ 0x00002f, 0x00003f, IGNIMM, N("ret") },
{ 0, 0, OOPS },
};
static struct insn tabroot[] = {
{ 0, 0, OP1B, T(m) },
};
struct disisa vcomp_isa_s = {
tabroot,
1,
1,
4,
};

View File

@ -234,7 +234,7 @@ static int test_arith(struct hwtest_ctx *ctx) {
/* store */
if (opc == 0x22)
continue;
/* waiti */
/* sleep */
if (opc == 0x26)
continue;
/* prevent bra to self */