* Bringing over SKY PKE disassembler feature from sky branch.

This commit is contained in:
Frank Ch. Eigler 1998-06-25 11:41:20 +00:00
parent dcf63a62ea
commit 56b6d49ae0
2 changed files with 394 additions and 42 deletions

View File

@ -532,7 +532,8 @@ pke_io_write_buffer(device *me_,
/* Reset the PKE */
/* Reset the simulated PKE hardware state. Preserve other internal
state. */
void
pke_reset(struct pke_device* me)
{
@ -542,14 +543,24 @@ pke_reset(struct pke_device* me)
/* clear registers, flag, other state */
memset(me->regs, 0, sizeof(me->regs));
me->fifo_qw_done = 0;
if ( me->trace_file != NULL )
{
fclose (me->trace_file);
me->trace_file = NULL;
}
/* Command options will remain alive over the reset. */
me->flags &= PKE_FLAG_TRACE_ON;
}
/* NOTE: Since disassembly / trace logs remain open across ordinary
simulated hardware resets, there may be a problem of producing a
trace file that has only partial results from the prior
operation. For the current PKE model, however, this cannot
happen as stalls & interrupts only occur *between* simulated
PKEcode executions. This means that our trace files ought remain
syntactically valid, despite resets. */
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n;%s RESET\n",
me->dev.name);
}
}
@ -653,12 +664,45 @@ pke_issue(SIM_DESC sd, struct pke_device* me)
}
}
/* open trace file if necessary */
if(me->trace_file == NULL &&
me->trace_file_name != NULL)
{
sky_open_file(& (me->trace_file),
me->trace_file_name,
(char *) NULL, _IOFBF );
/* print disassembly header */
fprintf(me->trace_file,
"\t.global %s_disassembly_tag\n"
"%s_disassembly_tag:\n",
me->dev.name, me->dev.name);
}
/* decode & execute */
/* order tests in decreasing order of frequency */
if(IS_PKE_CMD(cmd, PKENOP))
pke_code_nop(me, fw);
else if(IS_PKE_CMD(cmd, PKEMSCAL))
pke_code_pkemscal(me, fw);
else if(IS_PKE_CMD(cmd, PKEMSCNT))
pke_code_pkemscnt(me, fw);
else if(me->pke_number == 1 && IS_PKE_CMD(cmd, PKEMSCALF))
pke_code_pkemscalf(me, fw);
else if(IS_PKE_CMD(cmd, UNPACK))
pke_code_unpack(me, fw);
else if(IS_PKE_CMD(cmd, STCYCL))
pke_code_stcycl(me, fw);
else if(IS_PKE_CMD(cmd, FLUSHE))
pke_code_flushe(me, fw);
else if(me->pke_number == 1 && IS_PKE_CMD(cmd, FLUSH))
pke_code_flush(me, fw);
else if(me->pke_number == 1 && IS_PKE_CMD(cmd, FLUSHA))
pke_code_flusha(me, fw);
else if(IS_PKE_CMD(cmd, DIRECT))
pke_code_direct(me, fw);
else if(IS_PKE_CMD(cmd, DIRECTHL))
pke_code_directhl(me, fw);
else if(me->pke_number == 1 && IS_PKE_CMD(cmd, OFFSET))
pke_code_offset(me, fw);
else if(me->pke_number == 1 && IS_PKE_CMD(cmd, BASE))
@ -667,22 +711,8 @@ pke_issue(SIM_DESC sd, struct pke_device* me)
pke_code_itop(me, fw);
else if(IS_PKE_CMD(cmd, STMOD))
pke_code_stmod(me, fw);
else if(me->pke_number == 1 && IS_PKE_CMD(cmd, MSKPATH3))
pke_code_mskpath3(me, fw);
else if(IS_PKE_CMD(cmd, PKEMARK))
pke_code_pkemark(me, fw);
else if(IS_PKE_CMD(cmd, FLUSHE))
pke_code_flushe(me, fw);
else if(me->pke_number == 1 && IS_PKE_CMD(cmd, FLUSH))
pke_code_flush(me, fw);
else if(me->pke_number == 1 && IS_PKE_CMD(cmd, FLUSHA))
pke_code_flusha(me, fw);
else if(IS_PKE_CMD(cmd, PKEMSCAL))
pke_code_pkemscal(me, fw);
else if(IS_PKE_CMD(cmd, PKEMSCNT))
pke_code_pkemscnt(me, fw);
else if(me->pke_number == 1 && IS_PKE_CMD(cmd, PKEMSCALF))
pke_code_pkemscalf(me, fw);
else if(IS_PKE_CMD(cmd, STMASK))
pke_code_stmask(me, fw);
else if(IS_PKE_CMD(cmd, STROW))
@ -691,12 +721,8 @@ pke_issue(SIM_DESC sd, struct pke_device* me)
pke_code_stcol(me, fw);
else if(IS_PKE_CMD(cmd, MPG))
pke_code_mpg(me, fw);
else if(IS_PKE_CMD(cmd, DIRECT))
pke_code_direct(me, fw);
else if(IS_PKE_CMD(cmd, DIRECTHL))
pke_code_directhl(me, fw);
else if(IS_PKE_CMD(cmd, UNPACK))
pke_code_unpack(me, fw);
else if(me->pke_number == 1 && IS_PKE_CMD(cmd, MSKPATH3))
pke_code_mskpath3(me, fw);
else if(cmd == TXVU_VIF_BRK_MASK)
{
sim_cpu *cpu = STATE_CPU (sd, 0);
@ -1194,6 +1220,16 @@ void
pke_code_nop(struct pke_device* me, unsigned_4 pkecode)
{
/* done */
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tVIFNOP%s\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E) ? "[i]" : ""));
}
pke_pc_advance(me, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
}
@ -1208,6 +1244,17 @@ pke_code_stcycl(struct pke_device* me, unsigned_4 pkecode)
PKE_REG_MASK_SET(me, CYCLE, WL, BIT_MASK_GET(imm, 8, 15));
PKE_REG_MASK_SET(me, CYCLE, CL, BIT_MASK_GET(imm, 0, 7));
/* done */
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tSTCYCL%s %d,%d\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E) ? "[i]" : ""),
BIT_MASK_GET(imm, 8, 15), BIT_MASK_GET(imm, 0, 7));
}
pke_pc_advance(me, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
}
@ -1227,6 +1274,17 @@ pke_code_offset(struct pke_device* me, unsigned_4 pkecode)
/* set TOPS = BASE */
PKE_REG_MASK_SET(me, TOPS, TOPS, PKE_REG_MASK_GET(me, BASE, BASE));
/* done */
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tOFFSET%s 0x%x\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E) ? "[i]" : ""),
imm);
}
pke_pc_advance(me, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
}
@ -1240,6 +1298,17 @@ pke_code_base(struct pke_device* me, unsigned_4 pkecode)
/* copy 10 bits to BASE field */
PKE_REG_MASK_SET(me, BASE, BASE, BIT_MASK_GET(imm, 0, 9));
/* done */
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tBASE%s 0x%x\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E) ? "[i]" : ""),
imm);
}
pke_pc_advance(me, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
}
@ -1253,6 +1322,17 @@ pke_code_itop(struct pke_device* me, unsigned_4 pkecode)
/* copy 10 bits to ITOPS field */
PKE_REG_MASK_SET(me, ITOPS, ITOPS, BIT_MASK_GET(imm, 0, 9));
/* done */
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tITOP%s 0x%x\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E) ? "[i]" : ""),
imm);
}
pke_pc_advance(me, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
}
@ -1264,8 +1344,25 @@ pke_code_stmod(struct pke_device* me, unsigned_4 pkecode)
int imm = BIT_MASK_GET(pkecode, PKE_OPCODE_IMM_B, PKE_OPCODE_IMM_E);
/* copy 2 bits to MODE register */
PKE_REG_MASK_SET(me, MODE, MDE, BIT_MASK_GET(imm, 0, 2));
PKE_REG_MASK_SET(me, MODE, MDE, BIT_MASK_GET(imm, 0, 1));
/* done */
if(me->trace_file != NULL)
{
char* mode;
if(BIT_MASK_GET(imm, 0, 1) == 0) mode = "direct";
else if(BIT_MASK_GET(imm, 0, 1) == 1) mode = "add";
else if(BIT_MASK_GET(imm, 0, 1) == 2) mode = "addrow";
else mode = "3"; /* invalid mode */
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tSTMOD%s %s\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E) ? "[i]" : ""),
mode);
}
pke_pc_advance(me, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
}
@ -1287,6 +1384,17 @@ pke_code_mskpath3(struct pke_device* me, unsigned_4 pkecode)
PKE_MEM_WRITE(me, GIF_REG_VIF_M3P, & gif_mode, 4);
/* done */
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tMSKPATH3%s %s\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E) ? "[i]" : ""),
(gif_mode ? "disable" : "enable"));
}
pke_pc_advance(me, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
}
@ -1301,6 +1409,17 @@ pke_code_pkemark(struct pke_device* me, unsigned_4 pkecode)
/* set MRK bit in STAT register - CPU2 v2.1 docs incorrect */
PKE_REG_MASK_SET(me, STAT, MRK, 1);
/* done */
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tMARK%s 0x%x\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E) ? "[i]" : ""),
imm);
}
pke_pc_advance(me, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
}
@ -1322,6 +1441,16 @@ pke_code_flushe(struct pke_device* me, unsigned_4 pkecode)
/* VU idle */
PKE_REG_MASK_SET(me, STAT, PEW, 0);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tFLUSHE%s\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E) ? "[i]" : ""));
}
pke_pc_advance(me, 1);
}
}
@ -1361,6 +1490,16 @@ pke_code_flush(struct pke_device* me, unsigned_4 pkecode)
{
/* all idle */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tFLUSH%s\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E) ? "[i]" : ""));
}
pke_pc_advance(me, 1);
}
}
@ -1400,6 +1539,16 @@ pke_code_flusha(struct pke_device* me, unsigned_4 pkecode)
{
/* all idle */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tFLUSHA%s\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E) ? "[i]" : ""));
}
pke_pc_advance(me, 1);
}
}
@ -1443,6 +1592,17 @@ pke_code_pkemscal(struct pke_device* me, unsigned_4 pkecode)
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tMSCAL%s 0x%x\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E) ? "[i]" : ""),
imm);
}
pke_pc_advance(me, 1);
}
}
@ -1488,6 +1648,15 @@ pke_code_pkemscnt(struct pke_device* me, unsigned_4 pkecode)
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tMSCNT\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc);
}
pke_pc_advance(me, 1);
}
}
@ -1548,6 +1717,16 @@ pke_code_pkemscalf(struct pke_device* me, unsigned_4 pkecode)
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tMSCALF 0x%x\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
imm);
}
pke_pc_advance(me, 1);
}
}
@ -1576,6 +1755,16 @@ pke_code_stmask(struct pke_device* me, unsigned_4 pkecode)
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tSTMASK 0x%x\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
*mask);
}
pke_pc_advance(me, 2);
}
else
@ -1613,6 +1802,19 @@ pke_code_strow(struct pke_device* me, unsigned_4 pkecode)
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tSTROW 0x%x,0x%x,0x%x,0x%x\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
* pke_pcrel_operand(me, 1),
* pke_pcrel_operand(me, 2),
* pke_pcrel_operand(me, 3),
* pke_pcrel_operand(me, 4));
}
pke_pc_advance(me, 5);
}
else
@ -1650,6 +1852,19 @@ pke_code_stcol(struct pke_device* me, unsigned_4 pkecode)
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tSTCOL 0x%x,0x%x,0x%x,0x%x\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
* pke_pcrel_operand(me, 1),
* pke_pcrel_operand(me, 2),
* pke_pcrel_operand(me, 3),
* pke_pcrel_operand(me, 4));
}
pke_pc_advance(me, 5);
}
else
@ -1697,6 +1912,17 @@ pke_code_mpg(struct pke_device* me, unsigned_4 pkecode)
/* set NUM */
PKE_REG_MASK_SET(me, NUM, NUM, num);
/* disassembly */
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tMPG 0x%x,0x%x\n",
me->dev.name, me->fifo_pc, me->qw_pc,
imm, num);
}
/* transfer VU instructions, one word-pair per iteration */
for(i=0; i<num; i++)
{
@ -1761,6 +1987,15 @@ pke_code_mpg(struct pke_device* me, unsigned_4 pkecode)
PKE_MEM_WRITE(me, vutrack_addr,
& source_addr,
4);
/* disassembly */
if(me->trace_file != NULL)
{
unsigned long opcodes[2] = { vu_upper_opcode, vu_lower_opcode };
fprintf(me->trace_file, "\t");
opcode_analyze(me->trace_file, opcodes);
fprintf(me->trace_file, "\n");
}
} /* VU xfer loop */
/* check NUM */
@ -1768,6 +2003,12 @@ pke_code_mpg(struct pke_device* me, unsigned_4 pkecode)
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\t.EndMpg\n"
"\t.EndDmaData\n");
}
pke_pc_advance(me, 1 + num*2);
}
} /* if FIFO full enough */
@ -1803,6 +2044,18 @@ pke_code_direct(struct pke_device* me, unsigned_4 pkecode)
/* "transferring" operand */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_XFER);
/* disassembly */
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\t%s 0x%x\n",
me->dev.name, me->fifo_pc, me->qw_pc,
(IS_PKE_CMD(pkecode, DIRECT) ? "DIRECT" : "DIRECTHL"),
imm);
}
/* transfer GPUIF quadwords, one word per iteration */
for(i=0; i<imm*4; i++)
@ -1819,11 +2072,25 @@ pke_code_direct(struct pke_device* me, unsigned_4 pkecode)
PKE_MEM_WRITE(me, GIF_PATH2_FIFO_ADDR,
& fifo_data,
16);
/* disassembly */
if(me->trace_file != NULL)
{
char buffer[200]; /* one line of disassembly */
gif_disassemble_pke_data(buffer, (quadword*) &fifo_data);
fprintf(me->trace_file, "\t%s\n", buffer);
}
} /* write collected quadword */
} /* GPUIF xfer loop */
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\t.EndDirect\n"
"\t.EndDmaData\n");
}
pke_pc_advance(me, 1 + imm*4);
} /* if FIFO full enough */
else
@ -1838,8 +2105,9 @@ pke_code_direct(struct pke_device* me, unsigned_4 pkecode)
void
pke_code_directhl(struct pke_device* me, unsigned_4 pkecode)
{
/* treat the same as DIRECTH */
/* treat the same as DIRECT */
pke_code_direct(me, pkecode);
/* dissassembly code handles DIRECT/DIRECTHL overloading */
}
@ -1887,6 +2155,32 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
/* "transferring" operand */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_XFER);
/* disassembly */
if(me->trace_file != NULL)
{
char unpack_type[8];
char flags[8];
sprintf(flags,"[%s%s%s%s]",
(m ? "m" : ""),
(usn ? "u" : ""),
(r ? "r" : ""),
(BIT_MASK_GET(pkecode, PKE_OPCODE_I_B, PKE_OPCODE_I_E) ? "i" : ""));
if(vn > 0)
sprintf(unpack_type, "V%d_%d",
(vn + 1),
(vl == 3 ? 5 : (32 >> vl)));
else
sprintf(unpack_type, "S_%d",
(vl == 3 ? 5 : (32 >> vl)));
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\tUNPACK%s %s,0x%x,0x%x\n",
me->dev.name, me->fifo_pc, me->qw_pc,
flags, unpack_type, imm, num);
}
/* don't check whether VU is idle */
@ -1975,6 +2269,12 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
/* compute packed vector dimensions */
int vectorbits = 0, unitbits = 0;
/* disassembly */
if(me->trace_file != NULL)
{
fprintf(me->trace_file, "\t; unpack input row %d\n", vector_num_in);
}
if(vl < 3) /* PKE_UNPACK_*_{32,16,8} */
{
unitbits = (32 >> vl);
@ -2018,6 +2318,18 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
/* fetch bitfield operand */
operand = pke_pcrel_operand_bits(me, bitoffset, unitbits, & source_addr);
/* disassemble */
if(me->trace_file != NULL && vl < 3) /* not for V4_5 */
{
char* data_size;
if(vl == 0) data_size=".word";
else if(vl == 1) data_size=".short";
else if(vl == 2) data_size=".byte";
else data_size = "<invalid>";
fprintf(me->trace_file, "\t%s 0x%x\n", data_size, operand);
}
/* selectively sign-extend; not for V4_5 1-bit value */
if(usn || unitbits == 1)
unpacked_data[i] = operand;
@ -2025,6 +2337,18 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
unpacked_data[i] = SEXT32(operand, unitbits-1);
}
/* disassemble */
if(me->trace_file != NULL && vl == 3) /* only for V4_5 */
{
unsigned short operand =
((unpacked_data[0] & 0x1f) << 0) |
((unpacked_data[1] & 0x1f) << 5) |
((unpacked_data[2] & 0x1f) << 10) |
((unpacked_data[3] & 0x1) << 15);
fprintf(me->trace_file, "\t.short 0x%x\n", operand);
}
/* set remaining top words in vector */
for(i=vn+1; i<4; i++)
{
@ -2136,6 +2460,12 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\t.EndUnpack\n"
"\t.EndDmaData\n");
}
pke_pc_advance(me, 1 + num_operands);
} /* PKE FIFO full enough */
else
@ -2163,6 +2493,17 @@ pke_code_error(struct pke_device* me, unsigned_4 pkecode)
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
}
if(me->trace_file != NULL)
{
fprintf(me->trace_file,
"\n; %s PC %d/%d\n"
"\tDmaCnt *\n"
"\t.word 0x%x\n"
"\t.EndDmaData\n",
me->dev.name, me->fifo_pc, me->qw_pc,
(long) pkecode);
}
/* advance over faulty word */
pke_pc_advance(me, 1);
}
@ -2189,6 +2530,9 @@ pke_options(struct pke_device *me, unsigned_4 option, char *option_string)
case SKY_OPT_TRACE_NAME:
if ( me->trace_file != NULL )
{
fprintf(me->trace_file,
"\n\n\tDmaEnd 0\n"
"\t.EndDmaData\n");
fclose (me->trace_file);
me->trace_file = NULL;
}
@ -2202,9 +2546,16 @@ pke_options(struct pke_device *me, unsigned_4 option, char *option_string)
case SKY_OPT_CLOSE:
if (me->trace_file != NULL)
fclose (me->trace_file);
{
fprintf(me->trace_file,
"\n\n\tDmaEnd 0\n"
"\t.EndDmaData\n");
fclose(me->trace_file);
me->trace_file = NULL;
}
if (me->fifo_trace_file != NULL )
fclose (me->fifo_trace_file);
me->fifo_trace_file = NULL;
break;
default:

View File

@ -9,18 +9,23 @@
/* External functions */
struct pke_fifo;
struct fifo_quadword;
struct pke_device;
void pke0_attach(SIM_DESC sd);
void pke0_issue(SIM_DESC sd);
void pke1_attach(SIM_DESC sd);
void pke1_issue(SIM_DESC sd);
/* structs declared below */
struct pke_fifo;
struct fifo_quadword;
void pke_options(struct pke_device *device, unsigned_4 option, char *option_string);
int read_pke_reg (struct pke_device *device, int regno, void *buf);
int write_pke_reg (struct pke_device *device, int regno, const void *buf);
int read_pke_pc (struct pke_device *device, void *buf);
int read_pke_pcx (struct pke_device *device, void *buf);
struct fifo_quadword* pke_fifo_access(struct pke_fifo*, unsigned_4 qwnum);
/* Quadword data type */
typedef unsigned_4 quadword[4];
@ -391,6 +396,7 @@ typedef struct pke_fifo
#define PKE_FIFO_ARCHEOLOGY 1000 /* number of old quadwords to keep as history */
/* PKE internal state: FIFOs, registers, handle to VU friend */
struct pke_device
{
@ -424,19 +430,15 @@ struct pke_device
int fifo_pc; /* 0 .. (fifo_num_elements-1): quadword index of next instruction */
int qw_pc; /* 0 .. 3: word index of next instruction */
/* Disassembly - file name and descriptor */
/* Disassembly state */
FILE *trace_file;
char *trace_file_name;
};
extern struct pke_device pke0_device;
extern struct pke_device pke1_device;
int read_pke_reg (struct pke_device *device, int regno, void *buf);
int write_pke_reg (struct pke_device *device, int regno, const void *buf);
int read_pke_pc (struct pke_device *device, void *buf);
int read_pke_pcx (struct pke_device *device, void *buf);
/* Flags for PKE.flags */
@ -489,6 +491,5 @@ int read_pke_pcx (struct pke_device *device, void *buf);
} \
} while(0)
void pke_options (struct pke_device *device, unsigned_4 option, char *option_string);
#endif /* H_PKE_H */