* Continuing unit testing of PKE simulator. It now successfully matches

the SCEI PKE simulator's output on its own test sample (tsv432.in).

	* sky-pke.h (PKE_MEM_READ, PKE_MEM_WRITE, PKE_REG_MASK_SET): Add
 	trace file records.

	* sky-pke.c: (pke_track_write): Removed function.  Replaced with
 	in-line modifications to VU tracking tables.
	(pke_attach): Attach VU tracking tables.  Use line buffering on
 	trace files.
	(pke_issue): Spit out additional trace records.
	(pke_pc_operand_bits): Correct bitfield masking error.
	(*): Replace sim_read/write with kludge PKE_MEM_READ/WRITE
 	throughout.
	(pke_code_unpack): Correct numerous small bugs in operand decoding
 	etc.
This commit is contained in:
Frank Ch. Eigler 1998-02-20 01:50:01 +00:00
parent 8d157f9653
commit 534a3d5cf1
2 changed files with 209 additions and 154 deletions

View File

@ -33,8 +33,6 @@ static unsigned_4 pke_pc_operand_bits(struct pke_device*, int bit_offset,
int bit_width, unsigned_4* sourceaddr);
static struct fifo_quadword* pke_pc_fifo(struct pke_device*, int operand_num,
unsigned_4** operand);
static int pke_track_write(struct pke_device*, const void* src, int len,
address_word dest, unsigned_4 sourceaddr);
static void pke_attach(SIM_DESC sd, struct pke_device* me);
enum pke_check_target { chk_vu, chk_path1, chk_path2, chk_path3 };
static int pke_check_stall(struct pke_device* me, enum pke_check_target what);
@ -149,13 +147,22 @@ pke_attach(SIM_DESC sd, struct pke_device* me)
(device*) me,
NULL /*buffer*/);
/* source-addr tracking word */
/* VU MEM0 tracking table */
sim_core_attach (sd, NULL, 0, access_read_write, 0,
(me->pke_number == 0) ? PKE0_SRCADDR : PKE1_SRCADDR,
sizeof(unsigned_4) /*nr_bytes*/,
((me->pke_number == 0) ? VU0_MEM0_SRCADDR_START : VU1_MEM0_SRCADDR_START),
((me->pke_number == 0) ? VU0_MEM0_SIZE : VU1_MEM0_SIZE) / 2,
0 /*modulo*/,
NULL,
zalloc(sizeof(unsigned_4)) /*buffer*/);
NULL,
NULL /*buffer*/);
/* VU MEM1 tracking table */
sim_core_attach (sd, NULL, 0, access_read_write, 0,
((me->pke_number == 0) ? VU0_MEM1_SRCADDR_START : VU1_MEM1_SRCADDR_START),
((me->pke_number == 0) ? VU0_MEM1_SIZE : VU1_MEM1_SIZE) / 4,
0 /*modulo*/,
NULL,
NULL /*buffer*/);
/* attach to trace file if appropriate */
{
@ -170,6 +177,7 @@ pke_attach(SIM_DESC sd, struct pke_device* me)
{
perror("VIF FIFO trace error on fopen");
}
setvbuf(me->fifo_trace_file, NULL, _IOLBF, 0);
}
}
}
@ -459,7 +467,7 @@ pke_io_write_buffer(device *me_,
{
/* time to grow */
int new_fifo_buffer_size = me->fifo_buffer_size + 20;
void* ptr = realloc((void*) me->fifo, new_fifo_buffer_size*sizeof(quadword));
void* ptr = realloc((void*) me->fifo, new_fifo_buffer_size*sizeof(struct fifo_quadword));
if(ptr == NULL)
{
@ -478,10 +486,10 @@ pke_io_write_buffer(device *me_,
fqw->word_class[2] = fqw->word_class[3] = wc_unknown;
memcpy((void*) fqw->data, me->fifo_qw_in_progress, sizeof(quadword));
ASSERT(sizeof(unsigned_4) == 4);
PKE_MEM_READ((SIM_ADDR) (me->pke_number == 0 ? DMA_D0_MADR : DMA_D1_MADR),
PKE_MEM_READ(me, (me->pke_number == 0 ? DMA_D0_MADR : DMA_D1_MADR),
& fqw->source_address,
4);
PKE_MEM_READ((SIM_ADDR) (me->pke_number == 0 ? DMA_D0_PKTFLAG : DMA_D1_PKTFLAG),
PKE_MEM_READ(me, (me->pke_number == 0 ? DMA_D0_PKTFLAG : DMA_D1_PKTFLAG),
& dma_tag_present,
4);
@ -491,7 +499,6 @@ pke_io_write_buffer(device *me_,
fqw->word_class[0] = fqw->word_class[1] = wc_dma;
}
me->fifo_num_elements++;
/* set FQC to "1" as FIFO is now not empty */
@ -538,6 +545,14 @@ pke_issue(SIM_DESC sd, struct pke_device* me)
(PKE_REG_MASK_GET(me, STAT, PIS) && !PKE_REG_MASK_GET(me, ERR, MII)))
{
/* try again next cycle; no state change */
/* trace command */
if(me->fifo_trace_file != NULL)
{
fprintf(me->fifo_trace_file, "# stalled STAT: %08lx\n",
(unsigned long) me->regs[PKE_REG_STAT][0]);
}
return;
}
@ -576,7 +591,8 @@ pke_issue(SIM_DESC sd, struct pke_device* me)
}
/* decoding */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_DECODE);
if(PKE_REG_MASK_GET(me, STAT, PPS) == PKE_REG_STAT_PPS_IDLE)
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_DECODE);
/* decode & execute */
if(IS_PKE_CMD(cmd, PKENOP))
@ -677,7 +693,7 @@ pke_pc_advance(struct pke_device* me, int num_words)
/* print trace record */
fprintf(me->fifo_trace_file,
"%d 0x%ux_%ux_%ux_%ux 0x%ux %c%c%c%c\n",
"%d 0x%08x_%08x_%08x_%08x 0x%08x %c%c%c%c\n",
(me->pke_number == 0 ? 0 : 1),
(unsigned) fq->data[3], (unsigned) fq->data[2],
(unsigned) fq->data[1], (unsigned) fq->data[0],
@ -803,13 +819,17 @@ pke_pc_operand_bits(struct pke_device* me, int bit_offset, int bit_width, unsign
unsigned_4* word = NULL;
unsigned_4 value;
struct fifo_quadword* fifo_operand;
int wordnumber, bitnumber;
wordnumber = bit_offset/32;
bitnumber = bit_offset%32;
/* find operand word with bitfield */
fifo_operand = pke_pc_fifo(me, (bit_offset / 32) + 1, &word);
ASSERT(word != 0);
fifo_operand = pke_pc_fifo(me, wordnumber + 1, &word);
ASSERT(word != NULL);
/* extract bitfield from word */
value = BIT_MASK_GET(*word, bit_offset % 32, bit_width);
value = BIT_MASK_GET(*word, bitnumber, bitnumber + bit_width - 1);
/* extract source addr from fifo word */
*source_addr = fifo_operand->source_address;
@ -819,39 +839,6 @@ pke_pc_operand_bits(struct pke_device* me, int bit_offset, int bit_width, unsign
/* Write a bunch of bytes into simulator memory. Store the given source address into the
PKE sourceaddr tracking word. */
int
pke_track_write(struct pke_device* me, const void* src, int len,
address_word dest, unsigned_4 sourceaddr)
{
int rc;
unsigned_4 no_sourceaddr = 0;
/* write srcaddr into PKE srcaddr tracking */
sim_write(NULL,
(SIM_ADDR) (me->pke_number == 0) ? PKE0_SRCADDR : PKE1_SRCADDR,
(void*) & sourceaddr,
sizeof(unsigned_4));
/* write bytes into simulator */
rc = sim_write(NULL,
(SIM_ADDR) dest,
(void*) src,
len);
/* clear srcaddr from PKE srcaddr tracking */
sim_write(NULL,
(SIM_ADDR) (me->pke_number == 0) ? PKE0_SRCADDR : PKE1_SRCADDR,
(void*) & no_sourceaddr,
sizeof(unsigned_4));
return rc;
}
/* check for stall conditions on indicated devices (path* only on PKE1), do not change status
return 0 iff no stall */
int
@ -861,15 +848,13 @@ pke_check_stall(struct pke_device* me, enum pke_check_target what)
unsigned_4 cop2_stat, gpuif_stat;
/* read status words */
sim_read(NULL,
(SIM_ADDR) (GIF_REG_STAT),
(void*) & gpuif_stat,
sizeof(unsigned_4));
sim_read(NULL,
(SIM_ADDR) (COP2_REG_STAT_ADDR),
(void*) & cop2_stat,
sizeof(unsigned_4));
ASSERT(sizeof(unsigned_4) == 4);
PKE_MEM_READ(me, (GIF_REG_STAT),
& gpuif_stat,
4);
PKE_MEM_READ(me, (COP2_REG_STAT_ADDR),
& cop2_stat,
4);
/* perform checks */
if(what == chk_vu)
@ -945,7 +930,8 @@ pke_code_stcycl(struct pke_device* me, unsigned_4 pkecode)
{
int imm = BIT_MASK_GET(pkecode, PKE_OPCODE_IMM_B, PKE_OPCODE_IMM_E);
/* copy immediate value into CYCLE reg */
me->regs[PKE_REG_CYCLE][0] = imm;
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 */
pke_pc_advance(me, 1);
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
@ -1158,11 +1144,12 @@ pke_code_pkemscal(struct pke_device* me, unsigned_4 pkecode)
/* compute new PC for VU */
vu_pc = BIT_MASK_GET(imm, 0, 15);
/* write new PC; callback function gets VU running */
sim_write(NULL,
(SIM_ADDR) (me->pke_number == 0 ? VU0_CIA : VU1_CIA),
(void*) & vu_pc,
sizeof(unsigned_4));
ASSERT(sizeof(unsigned_4) == 4);
PKE_MEM_WRITE(me, (me->pke_number == 0 ? VU0_CIA : VU1_CIA),
& vu_pc,
4);
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
@ -1195,16 +1182,16 @@ pke_code_pkemscnt(struct pke_device* me, unsigned_4 pkecode)
pke_flip_dbf(me);
/* read old PC */
sim_read(NULL,
(SIM_ADDR) (me->pke_number == 0 ? VU0_CIA : VU1_CIA),
(void*) & vu_pc,
sizeof(unsigned_4));
ASSERT(sizeof(unsigned_4) == 4);
PKE_MEM_READ(me, (me->pke_number == 0 ? VU0_CIA : VU1_CIA),
& vu_pc,
4);
/* rewrite new PC; callback function gets VU running */
sim_write(NULL,
(SIM_ADDR) (me->pke_number == 0 ? VU0_CIA : VU1_CIA),
(void*) & vu_pc,
sizeof(unsigned_4));
ASSERT(sizeof(unsigned_4) == 4);
PKE_MEM_WRITE(me, (me->pke_number == 0 ? VU0_CIA : VU1_CIA),
& vu_pc,
4);
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
@ -1255,11 +1242,12 @@ pke_code_pkemscalf(struct pke_device* me, unsigned_4 pkecode)
/* compute new PC for VU */
vu_pc = BIT_MASK_GET(imm, 0, 15);
/* write new PC; callback function gets VU running */
sim_write(NULL,
(SIM_ADDR) (me->pke_number == 0 ? VU0_CIA : VU1_CIA),
(void*) & vu_pc,
sizeof(unsigned_4));
/* rewrite new PC; callback function gets VU running */
ASSERT(sizeof(unsigned_4) == 4);
PKE_MEM_WRITE(me, (me->pke_number == 0 ? VU0_CIA : VU1_CIA),
& vu_pc,
4);
/* done */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_IDLE);
@ -1399,37 +1387,51 @@ pke_code_mpg(struct pke_device* me, unsigned_4 pkecode)
/* "transferring" operand */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_XFER);
/* transfer VU instructions, one word per iteration */
for(i=0; i<num*2; i++)
/* set NUM */
PKE_REG_MASK_SET(me, NUM, NUM, num);
/* transfer VU instructions, one word-pair per iteration */
for(i=0; i<num; i++)
{
address_word vu_addr_base, vu_addr;
address_word vutrack_addr_base, vutrack_addr;
unsigned_4 vu_opcode[2];
unsigned_4* operand;
struct fifo_quadword* fq = pke_pc_fifo(me, num, & operand);
/* set NUM */
PKE_REG_MASK_SET(me, NUM, NUM, (num*2 - i) / 2);
struct fifo_quadword* fq;
int next_num;
/* decrement NUM */
next_num = PKE_REG_MASK_GET(me, NUM, NUM) - 1;
PKE_REG_MASK_SET(me, NUM, NUM, next_num);
/* imm: in 64-bit units for MPG instruction */
/* VU*_MEM0 : instruction memory */
vu_addr_base = (me->pke_number == 0) ?
VU0_MEM0_WINDOW_START : VU0_MEM0_WINDOW_START;
vu_addr = vu_addr_base + (imm*2) + i;
vu_addr = vu_addr_base + (imm + i) *2;
/* XXX: overflow check! */
/* VU*_MEM0_TRACK : source-addr tracking table */
vutrack_addr_base = (me->pke_number == 0) ?
VU0_MEM0_SRCADDR_START : VU1_MEM0_SRCADDR_START;
vutrack_addr = vu_addr_base + (imm*2) + i;
vutrack_addr = vu_addr_base + imm + i;
/* Fetch operand words */
fq = pke_pc_fifo(me, num*2 + i, & operand);
vu_opcode[0] = *operand;
vu_opcode[1] = *pke_pc_operand(me, num*2 + i + 1);
/* write data into VU memory */
pke_track_write(me, operand, sizeof(unsigned_4),
vu_addr, fq->source_address);
ASSERT(sizeof(vu_opcode) == 8);
PKE_MEM_WRITE(me, vu_addr,
vu_opcode,
8);
/* write srcaddr into VU srcaddr tracking table */
sim_write(NULL,
(SIM_ADDR) vutrack_addr,
(void*) & fq->source_address,
sizeof(unsigned_4));
PKE_MEM_WRITE(me, vutrack_addr,
& fq->source_address,
4);
} /* VU xfer loop */
/* check NUM */
@ -1479,18 +1481,18 @@ pke_code_direct(struct pke_device* me, unsigned_4 pkecode)
/* transfer GPUIF quadwords, one word per iteration */
for(i=0; i<imm*4; i++)
{
unsigned_4* operand;
struct fifo_quadword* fq = pke_pc_fifo(me, num, &operand);
unsigned_4* operand = pke_pc_operand(me, num);
/* collect word into quadword */
fifo_data[i%4] = *operand;
fifo_data[i % 4] = *operand;
/* write to GPUIF FIFO only with full word */
if(i%4 == 3)
/* write to GPUIF FIFO only with full quadword */
if(i % 4 == 3)
{
address_word gpuif_fifo = GIF_PATH2_FIFO_ADDR+(i/4);
pke_track_write(me, fifo_data, sizeof(quadword),
(SIM_ADDR) gpuif_fifo, fq->source_address);
ASSERT(sizeof(fifo_data) == 16);
PKE_MEM_WRITE(me, GIF_PATH2_FIFO_ADDR,
fifo_data,
16);
} /* write collected quadword */
} /* GPUIF xfer loop */
@ -1531,10 +1533,7 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
int sx = BIT_MASK_GET(imm, 14, 14);
int n, num_operands;
unsigned_4* last_operand_word;
/* map zero to max+1 */
if(num==0) num=0x100;
unsigned_4* last_operand_word = NULL;
/* compute PKEcode length, as given in CPU2 spec, v2.1 pg. 11 */
if(wl <= cl)
@ -1544,11 +1543,13 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
num_operands = ((32 >> vl) * (vn+1) * n)/32;
/* confirm that FIFO has enough words in it */
last_operand_word = pke_pc_operand(me, num_operands);
if(last_operand_word != NULL)
if(num_operands > 0)
last_operand_word = pke_pc_operand(me, num_operands);
if(last_operand_word != NULL || num_operands == 0)
{
address_word vu_addr_base;
int vector_num;
address_word vu_addr_base, vutrack_addr_base;
address_word vu_addr_max_size;
int vector_num_out, vector_num_in;
/* "transferring" operand */
PKE_REG_MASK_SET(me, STAT, PPS, PKE_REG_STAT_PPS_XFER);
@ -1557,49 +1558,71 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
/* compute VU address base */
if(me->pke_number == 0)
vu_addr_base = VU0_MEM1_WINDOW_START + BIT_MASK_GET(imm, 0, 9);
{
vu_addr_base = VU0_MEM1_WINDOW_START + 16 * BIT_MASK_GET(imm, 0, 9);
vu_addr_max_size = VU0_MEM1_SIZE;
vutrack_addr_base = VU0_MEM1_SRCADDR_START + 4 * BIT_MASK_GET(imm, 0, 9);
}
else
{
vu_addr_base = VU1_MEM1_WINDOW_START + BIT_MASK_GET(imm, 0, 9);
if(r) vu_addr_base += PKE_REG_MASK_GET(me, TOPS, TOPS);
vu_addr_base = VU1_MEM1_WINDOW_START + 16 * BIT_MASK_GET(imm, 0, 9);
vu_addr_max_size = VU1_MEM1_SIZE;
vutrack_addr_base = VU1_MEM1_SRCADDR_START + 4 * BIT_MASK_GET(imm, 0, 9);
if(r) /* double-buffering */
{
vu_addr_base += 16 * PKE_REG_MASK_GET(me, TOPS, TOPS);
vutrack_addr_base += 4 * PKE_REG_MASK_GET(me, TOPS, TOPS);
}
}
/* set NUM */
PKE_REG_MASK_SET(me, NUM, NUM, num);
PKE_REG_MASK_SET(me, NUM, NUM, num == 0 ? 0x100 : num );
/* transfer given number of vectors */
vector_num = 0; /* output vector number being processed */
vector_num_out = 0; /* output vector number being processed */
vector_num_in = 0; /* argument vector number being processed */
do
{
quadword vu_old_data;
quadword vu_new_data;
quadword unpacked_data;
address_word vu_addr;
address_word vutrack_addr;
unsigned_4 source_addr = 0;
int i;
int next_num;
/* decrement NUM */
PKE_REG_MASK_SET(me, NUM, NUM,
PKE_REG_MASK_GET(me, NUM, NUM) - 1);
next_num = PKE_REG_MASK_GET(me, NUM, NUM) - 1;
PKE_REG_MASK_SET(me, NUM, NUM, next_num);
/* compute VU destination address, as bytes in R5900 memory */
if(cl >= wl)
{
/* map zero to max+1 */
if(wl == 0) wl = 0x0100;
vu_addr = vu_addr_base + 16*(cl*(vector_num/wl) + (vector_num%wl));
vu_addr = vu_addr_base + 16*(cl*(vector_num_out/wl) + (vector_num_out%wl));
}
else
vu_addr = vu_addr_base + 16*vector_num;
vu_addr = vu_addr_base + 16*vector_num_out;
/* check for vu_addr overflow */
while(vu_addr >= vu_addr_base + vu_addr_max_size)
vu_addr -= vu_addr_max_size;
/* compute address of tracking table entry */
vutrack_addr = vutrack_addr_base + ((signed_8)vu_addr - (signed_8)vu_addr_base) / 4;
/* XXX: can vu_addr overflow? */
/* read old VU data word at address */
sim_read(NULL, (SIM_ADDR) vu_addr, (void*) & vu_old_data, sizeof(vu_old_data));
ASSERT(sizeof(vu_old_data) == 16);
PKE_MEM_READ(me, vu_addr,
vu_old_data,
16);
/* For cyclic unpack, next operand quadword may come from instruction stream
or be zero. */
if((cl < wl) && ((vector_num % wl) >= cl)) /* wl != 0, set above */
if((cl < wl) && ((vector_num_out % wl) >= cl)) /* wl != 0, set above */
{
/* clear operand - used only in a "indeterminate" state */
for(i = 0; i < 4; i++)
@ -1634,7 +1657,7 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
/* offset in bits in current operand word */
int bitoffset =
(vector_num * vectorbits) + (i * unitbits); /* # of bits from PKEcode */
(vector_num_in * vectorbits) + (i * unitbits); /* # of bits from PKEcode */
/* last unit of V4_5 is only one bit wide */
if(vl == 3 && vn == 3 && i == 3) /* PKE_UNPACK_V4_5 */
@ -1644,20 +1667,23 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
operand = pke_pc_operand_bits(me, bitoffset, unitbits, & source_addr);
/* selectively sign-extend; not for V4_5 1-bit value */
if(sx && unitbits > 0)
if(sx && unitbits > 1)
unpacked_data[i] = SEXT32(operand, unitbits-1);
else
unpacked_data[i] = operand;
}
/* consumed a vector from the PKE instruction stream */
vector_num_in ++;
} /* unpack word from instruction operand */
/* compute replacement word */
if(m) /* use mask register? */
{
/* compute index into mask register for this word */
int mask_index = PKE_LIMIT(vector_num % wl, 3); /* wl != 0, set above */
int mask_index = PKE_LIMIT(vector_num_out % wl, 3); /* wl != 0, set above */
for(i=0; i<3; i++) /* loop over columns */
for(i=0; i<4; i++) /* loop over columns */
{
int mask_op = PKE_MASKREG_GET(me, mask_index, i);
unsigned_4* masked_value = NULL;
@ -1680,7 +1706,7 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
break;
case PKE_MASKREG_COLUMN: /* exploit C0..C3 contiguity */
masked_value = & me->regs[PKE_REG_C0 + PKE_LIMIT(vector_num,3)][0];
masked_value = & me->regs[PKE_REG_C0 + mask_index][0];
break;
case PKE_MASKREG_NOTHING:
@ -1727,11 +1753,19 @@ pke_code_unpack(struct pke_device* me, unsigned_4 pkecode)
}
/* write replacement word */
pke_track_write(me, vu_new_data, sizeof(vu_new_data),
(SIM_ADDR) vu_addr, source_addr);
ASSERT(sizeof(vu_new_data) == 16);
PKE_MEM_WRITE(me, vu_addr,
vu_new_data,
16);
/* write tracking address */
ASSERT(sizeof(unsigned_4) == 4);
PKE_MEM_WRITE(me, vutrack_addr,
& source_addr,
4);
/* next vector please */
vector_num ++;
vector_num_out ++;
} /* vector transfer loop */
while(PKE_REG_MASK_GET(me, NUM, NUM) > 0);

View File

@ -245,11 +245,6 @@ typedef unsigned_4 quadword[4];
#define PKE_REG_ERR_MII_B 0
/* source-addr for words written to VU/GPUIF ports */
#define PKE0_SRCADDR 0x20000020 /* from 1998-01-22 e-mail plans */
#define PKE1_SRCADDR 0x20000024 /* from 1998-01-22 e-mail plans */
/* UNPACK opcodes */
#define PKE_UNPACK(vn,vl) ((vn) << 2 | (vl))
#define PKE_UNPACK_S_32 PKE_UNPACK(0, 0)
@ -300,8 +295,9 @@ typedef unsigned_4 quadword[4];
/* set bitfield value */
#define BIT_MASK_SET(lvalue,begin,end,value) \
do { \
lvalue &= ~BIT_MASK_BTW(begin,end); \
lvalue |= (((value) << (begin)) & BIT_MASK_BTW(begin,end)); \
ASSERT((begin) <= (end)); \
(lvalue) &= ~BIT_MASK_BTW((begin),(end)); \
(lvalue) |= ((value) << (begin)) & BIT_MASK_BTW((begin),(end)); \
} while(0)
/* get bitfield value */
@ -309,18 +305,21 @@ do { \
(((rvalue) & BIT_MASK_BTW(begin,end)) >> (begin))
/* e.g., BIT_MASK_GET(0000111100001111, 2, 8) = 0000000100001100 */
/* get bitfield value, sign-extended to given bit number */
#define BIT_MASK_GET_SX(rvalue,begin,end,sx) \
(BIT_MASK_GET(rvalue,begin,end) | ((BIT_MASK_GET(rvalue,begin,end) & BIT_MASK_BTW(end,end)) ? BIT_MASK_BTW(end,sx) : 0))
/* e.g., BIT_MASK_GET_SX(0000111100001111, 2, 8, 15) = 1111111100001100 */
/* These ugly macro hacks allow succinct bitfield accesses */
/* set a bitfield in a register by "name" */
#define PKE_REG_MASK_SET(me,reg,flag,value) \
BIT_MASK_SET(((me)->regs[PKE_REG_##reg][0]), \
PKE_REG_##reg##_##flag##_B, PKE_REG_##reg##_##flag##_E, \
(value))
do { \
unsigned_4 old = BIT_MASK_GET(((me)->regs[PKE_REG_##reg][0]), \
PKE_REG_##reg##_##flag##_B, PKE_REG_##reg##_##flag##_E); \
BIT_MASK_SET(((me)->regs[PKE_REG_##reg][0]), \
PKE_REG_##reg##_##flag##_B, PKE_REG_##reg##_##flag##_E, \
(value)); \
if((me)->fifo_trace_file != NULL) \
{ \
if(old != (value)) \
fprintf((me)->fifo_trace_file, "# Reg %s:%s = 0x%x\n", #reg, #flag, (unsigned)(value)); \
} \
} while(0)
/* get a bitfield from a register by "name" */
#define PKE_REG_MASK_GET(me,reg,flag) \
@ -390,18 +389,40 @@ struct pke_device
/* Kludge alert */
#define PKE_MEM_READ(addr,data,size) \
do { sim_cpu* cpu; cpu = STATE_CPU(CURRENT_STATE, 0); \
*(data) = sim_core_read_aligned_##size(cpu, CIA_GET(cpu), sim_core_read_map, \
(addr)); } while(0)
#define PKE_MEM_READ(me,addr,data,size) \
do { \
sim_cpu* cpu = STATE_CPU(CURRENT_STATE, 0); \
unsigned_##size value = \
sim_core_read_aligned_##size(cpu, CIA_GET(cpu), sim_core_read_map, \
(SIM_ADDR)(addr)); \
memcpy((unsigned_##size*) (data), (void*) & value, size); \
if(me->fifo_trace_file != NULL) \
{ \
int i; \
fprintf((me)->fifo_trace_file, "# Read %2d bytes from ", size); \
fprintf((me)->fifo_trace_file, "0x%08lx: ", (unsigned long)(addr)); \
for(i=0; i<size; i++) \
fprintf((me)->fifo_trace_file, " %02x", ((unsigned_1*)(& value))[i]); \
fprintf((me)->fifo_trace_file, "\n"); \
} \
} while(0)
#define PKE_MEM_WRITE(addr,data,size) \
do { sim_cpu* cpu; cpu = STATE_CPU(CURRENT_STATE, 0); \
#define PKE_MEM_WRITE(me,addr,data,size) \
do { sim_cpu* cpu = STATE_CPU(CURRENT_STATE, 0); \
unsigned_##size value; \
memcpy((void*) value, (data), size); \
memcpy((void*) & value, (unsigned_##size*)(data), size); \
sim_core_write_aligned_##size(cpu, CIA_GET(cpu), sim_core_write_map, \
(addr), value); } while(0)
(SIM_ADDR)(addr), value); \
if((me)->fifo_trace_file != NULL) \
{ \
int i; \
fprintf((me)->fifo_trace_file, "# Write %2d bytes to ", size); \
fprintf((me)->fifo_trace_file, "0x%08lx: ", (unsigned long)(addr)); \
for(i=0; i<size; i++) \
fprintf((me)->fifo_trace_file, " %02x", ((unsigned_1*)(& value))[i]); \
fprintf((me)->fifo_trace_file, "\n"); \
} \
} while(0)