From: Frank Ch. Eigler Date: Fri, 20 Mar 1998 22:12:06 +0000 (+0000) Subject: * Monster bug fixes & improvements from the last two days' demo-testing work. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=121d6745bc73a2e3f33e51a5c07db966eb9a5fbe;p=binutils-gdb.git * Monster bug fixes & improvements from the last two days' demo-testing work. * sky-pke.h (pke_fifo*): Exported these formerly private functions. (pke_device): Added FIFO cache fields. * sky-pke.c (pke_fifo_reset): New function for GPUIF client - clear FIFO contents. (pke_pcrel_fifo): Added caching facility to prevent O(n^2) cost for searching for consecutive operand words. * sky-libvpe.c (MEM, uMEM): New/changed macros that perform modulo calculations to handle out-of-range VU memory addresses. (*): Replaced many previous uses of MEM[] and state->uMEM[] with calls to above macros. * sky-vu.h (struct VectorUnitState): Added qw/dw size fields for MEM/uMEM buffers, for overflow prevention. Renamed MEM/uMEM fields to catch all their prior users. * sky-vu0.c (vu0_attach): Manually align MEM0/MEM1 buffers to force 16-byte alignment. (zalloc is not enough.) * sky-vu1.c (vu1_attach): Ditto. (init_vu): Store buffer sizes from allocation into VectorUnitState. * sky-gpuif.h (GifPath): Use a pke_fifo strucf instead of temporary fixed-size array for flexible FIFO sizing. * sky-gpuif.c (SKY_GPU2_REFRESH): This is now an integer value to be used as a modulus for periodic refresh. (refresh): New function to send GPU2 refresh code periodically. (*): Use pke_fifo calls to en/dequeue GPUIF tags & operands. * sky-pke.h (struct pke_device): Added fields to allow caching of results from recent FIFO searches. --- diff --git a/sim/mips/sky-pke.c b/sim/mips/sky-pke.c index 1689fc1513d..cf7408b0684 100644 --- a/sim/mips/sky-pke.c +++ b/sim/mips/sky-pke.c @@ -30,10 +30,6 @@ static int pke_io_write_buffer(device*, const void*, int, address_word, unsigned, sim_cpu*, sim_cia); static void pke_reset(struct pke_device*); static void pke_issue(SIM_DESC, struct pke_device*); -static unsigned_4 pke_fifo_flush(struct pke_fifo*); -static struct fifo_quadword* pke_fifo_fit(struct pke_fifo*); -static inline struct fifo_quadword* pke_fifo_access(struct pke_fifo*, unsigned_4 qwnum); -static void pke_fifo_old(struct pke_fifo*, unsigned_4 qwnum); static void pke_pc_advance(struct pke_device*, int num_words); static struct fifo_quadword* pke_pcrel_fifo(struct pke_device*, int operand_num, unsigned_4** operand); @@ -81,6 +77,7 @@ struct pke_device pke0_device = {}, 0, /* FIFO write buffer */ { NULL, 0, 0, 0 }, /* FIFO */ NULL, /* FIFO trace file */ + -1, -1, 0, 0, 0, /* invalid FIFO cache */ 0, 0 /* pc */ }; @@ -93,6 +90,7 @@ struct pke_device pke1_device = {}, 0, /* FIFO write buffer */ { NULL, 0, 0, 0 }, /* FIFO */ NULL, /* FIFO trace file */ + -1, -1, 0, 0, 0, /* invalid FIFO cache */ 0, 0 /* pc */ }; @@ -683,6 +681,27 @@ pke_fifo_flush(struct pke_fifo* fifo) +/* Clear out contents of FIFO; make it really empty. */ + +void +pke_fifo_reset(struct pke_fifo* fifo) +{ + int i; + + /* clear fifo quadwords */ + for(i=0; inext; i++) + { + zfree(fifo->quadwords[i]); + fifo->quadwords[i] = NULL; + } + + /* reset pointers */ + fifo->origin = 0; + fifo->next = 0; +} + + + /* Make space for the next quadword in the FIFO. Allocate/enlarge FIFO pointer block if necessary. Return a pointer to it. */ @@ -886,15 +905,29 @@ pke_pc_advance(struct pke_device* me, int num_words) struct fifo_quadword* pke_pcrel_fifo(struct pke_device* me, int operand_num, unsigned_4** operand) { - int num = operand_num; + int num; int new_qw_pc, new_fifo_pc; struct fifo_quadword* fq = NULL; - ASSERT(num > 0); + /* check for validity of last search results in cache */ + if(me->last_fifo_pc == me->fifo_pc && + me->last_qw_pc == me->qw_pc && + operand_num > me->last_num) + { + /* continue search from last stop */ + new_fifo_pc = me->last_new_fifo_pc; + new_qw_pc = me->last_new_qw_pc; + num = operand_num - me->last_num; + } + else + { + /* start search from scratch */ + new_fifo_pc = me->fifo_pc; + new_qw_pc = me->qw_pc; + num = operand_num; + } - /* snapshot current pointers */ - new_fifo_pc = me->fifo_pc; - new_qw_pc = me->qw_pc; + ASSERT(num > 0); /* printf("pke %d pcrel_fifo operand_num %d\n", me->pke_number, operand_num); */ @@ -944,6 +977,15 @@ pke_pcrel_fifo(struct pke_device* me, int operand_num, unsigned_4** operand) /* annote the word where the pseudo-PC lands as an PKE operand */ ASSERT(fq->word_class[new_qw_pc] == wc_pkedata || fq->word_class[new_qw_pc] == wc_unknown); fq->word_class[new_qw_pc] = wc_pkedata; + + /* store search results in cache */ + /* keys */ + me->last_fifo_pc = me->fifo_pc; + me->last_qw_pc = me->qw_pc; + /* values */ + me->last_num = operand_num; + me->last_new_fifo_pc = new_fifo_pc; + me->last_new_qw_pc = new_qw_pc; } return fq; diff --git a/sim/mips/sky-pke.h b/sim/mips/sky-pke.h index 081b8f1c2e9..59558420ab0 100644 --- a/sim/mips/sky-pke.h +++ b/sim/mips/sky-pke.h @@ -15,6 +15,16 @@ 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; + +unsigned_4 pke_fifo_flush(struct pke_fifo*); +void pke_fifo_reset(struct pke_fifo*); +struct fifo_quadword* pke_fifo_fit(struct pke_fifo*); +struct fifo_quadword* pke_fifo_access(struct pke_fifo*, unsigned_4 qwnum); +void pke_fifo_old(struct pke_fifo*, unsigned_4 qwnum); + /* Quadword data type */ @@ -344,7 +354,8 @@ enum wordclass wc_dma = 'D', wc_pkecode = 'P', wc_unknown = '?', - wc_pkedata = '.' + wc_pkedata = '.', + wc_gpuiftag = 'g' }; @@ -361,13 +372,13 @@ struct fifo_quadword /* quadword FIFO structure for PKE */ -struct pke_fifo +typedef struct pke_fifo { struct fifo_quadword** quadwords; /* pointer to fifo quadwords */ unsigned_4 origin; /* quadword serial number of quadwords[0] */ unsigned_4 length; /* length of quadword pointer array: 0..N */ unsigned_4 next; /* relative index of first unfilled quadword: 0..length-1 */ -}; +} pke_fifo; #define PKE_FIFO_GROW_SIZE 1000 /* number of quadword pointers to allocate */ #define PKE_FIFO_ARCHEOLOGY 1000 /* number of old quadwords to keep as history */ @@ -394,6 +405,13 @@ struct pke_device struct pke_fifo fifo; /* array of FIFO quadword pointers */ FILE* fifo_trace_file; /* stdio stream open in append mode, or 0 for no trace */ + /* FIFO cache -- curry last search pke_pcrel_fifo results */ + unsigned_4 last_fifo_pc; + unsigned_4 last_qw_pc; + unsigned_4 last_num; + unsigned_4 last_new_fifo_pc; + unsigned_4 last_new_qw_pc; + /* PC */ int fifo_pc; /* 0 .. (fifo_num_elements-1): quadword index of next instruction */ int qw_pc; /* 0 .. 3: word index of next instruction */ diff --git a/sim/mips/sky-vu0.c b/sim/mips/sky-vu0.c index ed52c1bc99e..dc42ce5cdce 100644 --- a/sim/mips/sky-vu0.c +++ b/sim/mips/sky-vu0.c @@ -7,6 +7,7 @@ #include "sky-device.h" #include "sky-vu0.h" +/* these are aligned versions of zalloc() pointers - do not zfree()! */ static char* vu0_mem0_buffer = 0; static char* vu0_mem1_buffer = 0; @@ -64,6 +65,7 @@ vu0_attach(SIM_DESC sd) NULL /*buffer*/); vu0_mem0_buffer = zalloc(VU0_MEM0_SIZE); + vu0_mem0_buffer = (void*) ALIGN_16((unsigned)vu0_mem0_buffer); sim_core_attach (sd, NULL, 0 /*level*/, @@ -76,6 +78,7 @@ vu0_attach(SIM_DESC sd) vu0_mem0_buffer /*buffer*/); vu0_mem1_buffer = zalloc(VU0_MEM1_SIZE); + vu0_mem1_buffer = (void*) ALIGN_16((unsigned)vu0_mem1_buffer); sim_core_attach (sd, NULL, 0 /*level*/, diff --git a/sim/mips/sky-vu1.c b/sim/mips/sky-vu1.c index 2f3e22c7eaf..5d478b52f7d 100644 --- a/sim/mips/sky-vu1.c +++ b/sim/mips/sky-vu1.c @@ -17,11 +17,14 @@ VectorUnitState vu1_state; #define sim_warning printf +/* these are aligned versions of zalloc() pointers - do not zfree()! */ static char* vu1_umem_buffer = 0; static char* vu1_mem_buffer = 0; void init_vu1(void); -void init_vu(VectorUnitState *state, char* umem_buffer, char* mem_buffer); +void init_vu(VectorUnitState *state, + char* umem_buffer, unsigned umem_dw_size, + char* mem_buffer, unsigned mem_qw_size); #if 0 static void dump_mem() { @@ -171,6 +174,7 @@ vu1_init(SIM_DESC sd) NULL /*buffer*/); vu1_umem_buffer = zalloc(VU1_MEM0_SIZE); + vu1_umem_buffer = (void*) ALIGN_16((unsigned)vu1_umem_buffer); sim_core_attach (sd, NULL, 0 /*level*/, @@ -182,7 +186,8 @@ vu1_init(SIM_DESC sd) 0 /*device*/, vu1_umem_buffer /*buffer*/); - vu1_mem_buffer = zalloc(VU1_MEM1_SIZE); + vu1_mem_buffer = zalloc(VU1_MEM1_SIZE + 2*sizeof(unsigned_16)); + vu1_mem_buffer = (void*) ALIGN_16((unsigned)vu1_mem_buffer); sim_core_attach (sd, NULL, 0 /*level*/, @@ -225,19 +230,25 @@ static void abend2(char *fmt, char* p) { void getoption(VectorUnitState* state); void init_vu1(void) { - init_vu(&vu1_state, &vu1_umem_buffer[0], &vu1_mem_buffer[0]); + init_vu(&vu1_state, + &vu1_umem_buffer[0], VU1_MEM0_SIZE/8, + &vu1_mem_buffer[0], VU1_MEM1_SIZE/16); } -void init_vu(VectorUnitState *state, char* umem_buffer, char* mem_buffer) +void init_vu(VectorUnitState *state, + char* umem_buffer, unsigned umem_dw_size, + char* mem_buffer, unsigned mem_qw_size) { FILE *fp; int i, j; u_long data[4]; /* set up memory buffers */ - state->uMEM = (uMEM_Entry_Type *) umem_buffer; - state->MEM = (MEM_Entry_Type*) mem_buffer; - + state->uMEM_buffer = (uMEM_Entry_Type *) umem_buffer; + state->uMEM_size = umem_dw_size; + state->MEM_buffer = (MEM_Entry_Type*) mem_buffer; + state->MEM_size = mem_qw_size; + /* set up run state */ state->runState = VU_READY;