* Monster bug fixes & improvements from the last two days' demo-testing work.
authorFrank Ch. Eigler <fche@redhat.com>
Fri, 20 Mar 1998 22:12:06 +0000 (22:12 +0000)
committerFrank Ch. Eigler <fche@redhat.com>
Fri, 20 Mar 1998 22:12:06 +0000 (22:12 +0000)
* 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.

sim/mips/sky-pke.c
sim/mips/sky-pke.h
sim/mips/sky-vu0.c
sim/mips/sky-vu1.c

index 1689fc1513dad065bdc1b4b39e62f3cafb7fe111..cf7408b0684785298e50f80d7f555e79726765d3 100644 (file)
@@ -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; i<fifo->next; 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;
index 081b8f1c2e9a76fcaa1cc5b49e02aa5fbd879c59..59558420ab0dcb23145b36943fd4b55d5e6af4a0 100644 (file)
@@ -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 */
index ed52c1bc99e437bcdede4ca78837726d94b98b44..dc42ce5cdcee445b78d69e470311052397b47604 100644 (file)
@@ -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*/,
index 2f3e22c7eaf217070b4e676cdd2f0b05317d4ea1..5d478b52f7d8111206594c0cdaa65226da042830 100644 (file)
@@ -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;