spinsim/pasmdebug2.c

449 lines
16 KiB
C
Executable File

/*******************************************************************************
' Author: Dave Hein
' Version 0.21
' Copyright (c) 2010, 2011
' See end of file for terms of use.
'******************************************************************************/
#include <stdio.h>
#include <string.h>
#include "interp.h"
#include "spinsim.h"
#define REG_PINA 0x1f4
extern char *hubram;
extern int32_t memsize;
extern int32_t loopcount;
extern int32_t cycleaccurate;
extern int32_t pin_val;
extern FILE *tracefile;
static char *condnames[16] = {
"if_never ", "if_nz_and_nc", "if_z_and_nc ", "if_nc ",
"if_nz_and_c ", "if_nz ", "if_z_ne_c ", "if_nz_or_nc ",
"if_z_and_c ", "if_z_eq_c ", "if_z ", "if_z_or_nc ",
"if_c ", "if_nz_or_c ", "if_z_or_c ", " "};
char *opcodes_lower[64] = {
"rdbyte","rdbytec","rdword","rdwordc","rdlong","rdlongc","rdaux","rdauxr",
"isob","notb","clrb","setb","setbc","setbnc","setbz","setbnz",
"andn","and","or","xor","muxc","muxnc","muxz","muxnz",
"ror","rol","shr","shl","rcr","rcl","sar","rev",
"mov","not","abs","neg","negc","negnc","negz","negnz",
"add","sub","addx","subx","adds","subs","addsx","subsx",
"sumc","sumnc","sumz","sumnz","min","max","mins","maxs",
"addabs","subabs","incmod","decmod","cmpsub","subr","mul","scl"};
char *opcodes_upper[62][4] = {
{"decod2", "decod2", "decod2", "decod2"},
{"decod3", "decod3", "decod3", "decod3"},
{"decod4", "decod4", "decod4", "decod4"},
{"decod5", "decod5", "decod5", "decod5"},
{"encod", "blmask", "encod", "blmask"},
{"onecnt", "zercnt", "onecnt", "zercnt"},
{"incpat", "incpat", "decpat", "decpat"},
{"splitb", "mergeb", "splitw", "mergew"},
{"getnib", "setnib", "getnib", "setnib"},
{"getnib", "setnib", "getnib", "setnib"},
{"getnib", "setnib", "getnib", "setnib"},
{"getnib", "setnib", "getnib", "setnib"},
{"getword","setword","getword","setword"},
{"setwrds","rolnib", "rolbyte","rolword"},
{"sets", "setd", "setx", "seti"},
{"cognew", "cognew", "waitcnt","waitcnt"},
{"getbyte","setbyte","getbyte","setbyte"},
{"getbyte","setbyte","getbyte","setbyte"},
{"setbyts","movbyts","packrgb","unpkrgb"},
{"addpix", "mulpix", "blnpix", "mixpix"},
{"jmpsw", "jmpsw", "jmpsw", "jmpsw"},
{"jmpswd", "jmpswd", "jmpswd", "jmpswd"},
{"ijz", "ijzd", "ijnz", "ijnzd"},
{"djz", "djzd", "djnz", "djnzd"},
{"testb", "testb", "testb", "testb"},
{"testn", "testn", "testn", "testn"},
{"test", "test", "test", "test"},
{"cmp", "cmp", "cmp", "cmp"},
{"cmpx", "cmpx", "cmpx", "cmpx"},
{"cmps", "cmps", "cmps", "cmps"},
{"cmpsx", "cmpsx", "cmpsx", "cmpsx"},
{"cmpr", "cmpr", "cmpr", "cmpr"},
{"coginit","waitvid","coginit","waitvid"},
{"coginit","waitvid","coginit","waitvid"},
{"coginit","waitvid","coginit","waitvid"},
{"coginit","waitvid","coginit","waitvid"},
{"waitpeq","waitpeq","waitpeq","waitpeq"},
{"waitpeq","waitpeq","waitpeq","waitpeq"},
{"waitpne","waitpne","waitpne","waitpne"},
{"waitpne","waitpne","waitpne","waitpne"},
{"wrbyte", "wrbyte", "wrword", "wrword"},
{"wrlong", "wrlong", "frac", "frac"},
{"wraux", "wraux", "wrauxr", "wrauxr"},
{"setacca","setacca","setaccb","setaccb"},
{"maca", "maca", "macb", "macb"},
{"mul32", "mul32", "mul32u", "mul32u"},
{"div32", "div32", "div32u", "div32u"},
{"div64", "div64", "div64u", "div64u"},
{"sqrt64", "sqrt64", "qsincos","qsincos"},
{"qarctan","qarctan","qrotate","qrotate"},
{"setsera","setsera","setserb","setserb"},
{"setctrs","setctrs","setwavs","setwavs"},
{"setfrqs","setfrqs","setphss","setphss"},
{"addphss","addphss","subphss","subphss"},
{"jp", "jp", "jpd", "jpd"},
{"jnp", "jnp", "jnpd", "jnpd"},
{"cfgpins","cfgpins","cfgpins","cfgpins"},
{"cfgpins","cfgpins","jmptask","jmptask"},
{"setxfr", "setxfr", "setmix", "setmix"},
{"jz", "jzd", "jnz", "jnzd"},
{"locbase","locbyte","locword","loclong"},
{"jmplist","locinst","augs", "augd"}};
int zci_upper[62][4] = {
{7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7},
{5, 5, 5, 5}, {5, 5, 5, 5}, {3, 3, 3, 3}, {1, 1, 1, 1},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {3, 3, 3, 3},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{7, 7, 7, 7}, {7, 7, 7, 7}, {1, 1, 1, 1}, {1, 1, 1, 1},
{7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7},
{7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{3, 3, 3, 3}, {3, 3, 3, 3}, {3, 3, 3, 3}, {3, 3, 3, 3},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};
char *opcodes_ind[16] = {
"invalid", "fixinda", "setinda", "setinda",
"fixindb", "fixinds", "invalid", "invalid",
"setindb", "invalid", "setinds", "setinds",
"setindb", "invalid", "setinds", "setinds"};
char *opcodes_16[14] = {
"locptra","locptrb","jmp","jmpd","call","calld","calla",
"callad","callb","callbd","callx","callxd","cally","callyd"};
char *opcodes_set1[49] = {
"cogid","taskid","locknew","getlfsr","getcnt","getcntx","getacal","getacah",
"getacbl","getacbh","getptra","getptrb","getptrx","getptry","serina","serinb",
"getmull","getmulh","getdivq","getdivr","getsqrt","getqx","getqy","getqz",
"getphsa","getphza","getcosa","getsina","getphsb","getphzb","getcosb","getsinb",
"pushzc","popzc","subcnt","getpix","binbcd","bcdbin","bingry","grybin",
"eswap4","eswap8","seussf","seussr","incd","decd","incds","decds","pop"};
char *opcodes_set2[] = {
"clkset", "cogstop", "lockset", "lockclr", "lockret", "rdwidec", "rdwide",
"wrwide", "getp", "getnp", "serouta", "seroutb", "cmpcnt", "waitpx",
"waitpr", "waitpf", "setzc", "setmap", "setxch", "settask", "setrace",
"saracca", "saraccb", "saraccs", "setptra", "setptrb", "addptra", "addptrb",
"subptra", "subptrb", "setwide", "setwidz", "setptrx", "setptry",
"addptrx", "addptry", "subptrx", "subptry", "passcnt", "wait", "offp",
"notp", "clrp", "setp", "setpc", "setpnc", "setpz", "stpnz", "div64d",
"sqrt32", "qlog", "qexp", "setqi", "setqz", "cfgdacs", "setdacs",
"cfgdac0", "cfgdac1", "cfgdac2", "cfgdac3", "setdac0", "setdac1",
"setdac2", "seddac3", "setctra", "setwava", "setfrqa", "setphsa",
"addphsa", "subphsa", "setvid", "setvidy", "setctrb", "setwavb", "setfrqb",
"setphsb", "addphsb", "subphsb", "setvidi", "setvidq", "setpix", "setpixz",
"setpixu", "setpixv", "setpixa", "setpixr", "setpixg", "setpixb",
"setpora", "setporb", "setporc", "setpord", "push"};
char *opcodes_set3[40] = {
"jmp", "jmpd", "call", "calld", "calla", "callad", "callb", "callbd",
"callx", "callxd", "cally", "callyd", "reta", "retad", "retb", "retbd",
"retx", "retxd", "rety", "retyd", "ret", "retd", "polctra", "polctrb",
"polvid", "capctra", "capctrb", "capctrs", "setpixw", "clracca", "clraccb",
"clraccs", "chkptrx", "chkptry", "syntra", "synctrb", "dcachex", "icachex",
"icachep", "icachen"};
int zci_set3[40] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0,
0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0};
char *GetOpname2(unsigned int instr, int *pzci)
{
int opcode = instr >> 25;
int zci = (instr >> 22) & 7;
int cond = (instr >> 18) & 15;
int src = instr & 0x1ff;
int dst = (instr >> 9) & 0x1ff;
int zc = zci >> 1;
//printf("opcode = $%2.2x, zci = %d\n", opcode, zci);
if (opcode < 64)
{
*pzci = 7;
return opcodes_lower[opcode];
}
else if(opcode < 126)
{
*pzci = zci_upper[opcode-64][zc];
return opcodes_upper[opcode-64][zc];
}
else if (opcode == 126 && zci == 0)
{
*pzci = 0;
return opcodes_ind[cond];
}
else if (opcode == 126)
{
*pzci = 0;
return opcodes_16[(zci-1)*2 + (dst >> 8)];
}
else if (src <= 48)
{
if (src < 44 || src == 48)
*pzci = 7;
else
*pzci = 5;
return opcodes_set1[src];
}
if (src < 64)
{
*pzci = 0;
return "invalid";
}
if (src < 128)
{
*pzci = 1;
return "repd";
}
if (src < 220)
{
if (src == 136 || src == 137 || src == 144)
*pzci = 7;
else if (src == 130 || src == 131)
*pzci = 3;
else
*pzci = 1;
return opcodes_set2[src-128];
}
if (src < 0xf4)
{
*pzci = 0;
return "invalid";
}
if (src <= 0x11b)
{
*pzci = zci_set3[src-0xf4];
return opcodes_set3[src-0xf4];
}
*pzci = 0;
return "invalid";
}
void StartPasmCog2(PasmVarsT *pasmvars, int32_t par, int32_t addr, int32_t cogid)
{
int32_t i;
// printf("\nStartPasmCog2: %8.8x, %8.8x, %d\n", par, addr, cogid);
par &= 0x3ffff;
addr &= 0x3fffc;
pasmvars->waitflag = 0;
pasmvars->cflag = 0;
pasmvars->zflag = 0;
pasmvars->pc = 0;
pasmvars->cogid = cogid;
pasmvars->state = 5;
pasmvars->ptra = par;
pasmvars->ptrb = addr;
pasmvars->ptrx = 0;
pasmvars->ptry = 0;
pasmvars->inda = 0x1f2;
pasmvars->indatop = 0;
pasmvars->indabot = 0;
pasmvars->indb = 0x1f3;
pasmvars->indbtop = 0;
pasmvars->indbbot = 0;
pasmvars->repcnt = 0;
pasmvars->repbot = 0;
pasmvars->reptop = 0;
pasmvars->repforever = 0;
pasmvars->dcachehubaddr = 0xffffffff;
pasmvars->dcachecogaddr = 0xffffffff;
pasmvars->instruct1 = 0;
pasmvars->instruct2 = 0;
pasmvars->instruct3 = 0;
pasmvars->instruct4 = 0;
pasmvars->pc1 = INVALIDATE_INSTR;
pasmvars->pc2 = INVALIDATE_INSTR;
pasmvars->pc3 = INVALIDATE_INSTR;
pasmvars->pc4 = INVALIDATE_INSTR;
pasmvars->retptr = 0;
pasmvars->acca = 0;
pasmvars->accb = 0;
pasmvars->mulcount = 0;
pasmvars->breakpnt = -1;
pasmvars->augsflag = 0;
pasmvars->augsvalue = 0;
pasmvars->augdflag = 0;
pasmvars->augdvalue = 0;
pasmvars->icachehubaddr[0] = 0xffffffff;
pasmvars->icachehubaddr[1] = 0xffffffff;
pasmvars->icachehubaddr[2] = 0xffffffff;
pasmvars->icachehubaddr[3] = 0xffffffff;
pasmvars->icachenotused[0] = 0;
pasmvars->icachenotused[1] = 0;
pasmvars->icachenotused[2] = 0;
pasmvars->icachenotused[3] = 0;
pasmvars->prefetch = 1;
for (i = 0; i < 0x1f4; i++)
{
pasmvars->mem[i] = LONG(addr);
addr += 4;
}
for (i = 0x1f4; i < 512; i++) pasmvars->mem[i] = 0;
}
void DebugPasmInstruction2(PasmVarsT *pasmvars)
{
int32_t i;
int32_t cflag = pasmvars->cflag;
int32_t zflag = pasmvars->zflag;
int32_t instruct, pc, cond, xflag;
int32_t opcode, zci;
int32_t srcaddr, dstaddr;
char *wzstr = "";
char *wcstr = "";
char opstr[20];
char *istr[3] = {" ", "#", "@"};
char *xstr[8] = {" ", "X", "I", "H", "C", "P", "W", "?"};
int zci_mask;
int32_t sflag, dflag, indirect, opcode_zci;
// Fetch the instruction
pc = pasmvars->pc4;
instruct = pasmvars->instruct4;
cond = (instruct >> 18) & 15;
// Extract parameters from the instruction
opcode = (instruct >> 25) & 127;
srcaddr = instruct & 511;
dstaddr = (instruct >> 9) & 511;
zci = (instruct >> 22) & 7;
opcode_zci = (opcode << 3) | zci;
// Decode the immediate flags for the source and destination fields
sflag = (opcode_zci >= 0x3ea) | (zci & 1);
dflag = (opcode >= 0x68 && opcode <= 0x7a && (zci & 2)) |
(opcode_zci >= 0x302 && opcode_zci <= 0x31f) |
(opcode != 0x7f && opcode_zci >= 0x3eb) |
(opcode == 0x7f && srcaddr >= 0x40 && srcaddr <= 0xdc && (zci & 1)) |
(opcode == 0x7f && srcaddr >= 0x100);
// Determine if indirect registers are used
indirect = (!sflag && (srcaddr & 0x1fe) == 0x1f2) |
(!dflag && (dstaddr & 0x1fe) == 0x1f2) |
(opcode_zci == 0x3f0);
if (indirect) cond = 0xf;
xflag = ((cond >> ((cflag << 1) | zflag)) & 1);
xflag ^= 1;
// Check if the instruction is invalidated in the pipeline
if (pc & INVALIDATE_INSTR)
{
pc &= ~INVALIDATE_INSTR;
xflag = 2;
}
if (pasmvars->waitflag && pasmvars->waitmode == WAIT_CACHE) xflag = 4;
else if (xflag == 4) xflag = 5;
if (pasmvars->waitflag)
{
if (pasmvars->waitmode == WAIT_CACHE)
xflag = 4;
else if (pasmvars->waitmode == WAIT_CNT)
xflag = 6;
else if (pasmvars->waitmode == WAIT_PIN)
xflag = 5;
else if (pasmvars->waitmode == WAIT_HUB)
xflag = 3;
else
xflag = 7;
}
strcpy(opstr, GetOpname2(instruct, &zci_mask));
zci &= zci_mask;
if (zci & 4) wzstr = " wz";
if (zci & 2) wcstr = " wc";
i = strlen(opstr);
while (i < 7) opstr[i++] = ' ';
opstr[i] = 0;
// Check for NOP
if (!instruct)
{
cond = 15;
if (xflag == 1) xflag = 0;
strcpy(opstr, "nop ");
}
// Check for REPS
if ((instruct & 0xffc00000) == 0xfac00000)
{
cond = 15;
if (xflag == 1) xflag = 0;
strcpy(opstr, "reps ");
}
// Check for AUGS or AUGD
if (opcode_zci >= 0x3ec && opcode_zci <= 0x3ef)
{
cond = 15;
if (xflag == 1) xflag = 0;
}
if (pasmvars->printflag - 2 < xflag && xflag != 0)
{
pasmvars->printflag = 0;
return;
}
fprintf(tracefile, "Cog %d: %8.8x ", pasmvars->cogid, loopcount);
fprintf(tracefile, "%4.4x %8.8x %s %s %s %s%3.3x, %s%3.3x%s%s", pc,
instruct, xstr[xflag], condnames[cond], opstr, istr[dflag], dstaddr,
istr[sflag], srcaddr, wzstr, wcstr);
}
/*
+------------------------------------------------------------------------------------------------------------------------------+
| TERMS OF USE: MIT License |
+------------------------------------------------------------------------------------------------------------------------------+
|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 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. |
+------------------------------------------------------------------------------------------------------------------------------+
*/