[patch] AltiVec support for PSIM.

matthew green mrg@cygnus.com
Thu Jan 3 20:56:00 GMT 2002


   
i wrote:
   yup.  i had a quick look at supporting :include: but that has a few
   issues with $(builddir) != $(srcdir) that don't look trivial to solve
   and the sim/igen code has changed somewhat...


actually, i got the sim/igen :include: support working without
too much trouble... mostly based on the sim/igen changes, but
modified to suit the old psim igen.. (this makes them ever so
much closer now, too :-).  i also copied the sim/igen -I ->
-Ggen-icache=N change and -I /include/path change.  i now have
an altivec.igen which has all the code except a couple of
deltas to some structures & code in the busy register/trace
code to deal with the VR regs.


here are the changed files.  i've not included the testsuite
or "altivec.igen" files again for bandwidth purposes.


OK now? :-)


.mrg.



	* sim/ppc/Makefile.in (tmp-igen): Pass -I $(srcdir) to igen.
	* sim/ppc/igen.c (main): Change -I to add include paths for :include:
	files.
	Implement -G as per sim/igen, with just gen-icache=N support.
	Call load_insn_table() with the built include path.

	* sim/ppc/ld-insn.c (parse_include_entry): New. Load an :include: file.
	(load_insn_table): New `includes' argument.  Look for :include:
	entries and call parse_include_entry() for them.
	(main): Adjust load_insn_table() call.
	* sim/ppc/ld-insn.h (model_include_fields): New enum.
	(load_insn_table): Update prototype.
	* sim/ppc/table.c (struct _open_table, struct _table): Rework
	structures to handle included files.
	(table_push): Move the guts of table_open() here

	* table.c (struct _open table, struct table): Make table object an
	indirect ptr to the current table file.
	(current_line, new_table_entry, next_line): Make file arg type
	open_table.
	(table_open): Use table_push.
	(table_entry_read): Point variable file at current table, at eof, pop
	last open table.

	* sim/ppc/misc.h (NZALLOC): New macro. From sim/igen.

	* table.h, table.c (table_push): New function.


Index: ppc/Makefile.in
===================================================================
RCS file: /cvs/src/src/sim/ppc/Makefile.in,v
retrieving revision 1.4
diff -p -r1.4 Makefile.in
*** Makefile.in	2002/01/04 00:00:54	1.4
--- Makefile.in	2002/01/04 04:42:19
*************** tmp-igen: igen ppc-instructions $(IGEN_O
*** 464,470 ****
  	./igen	$(IGEN_FLAGS) \
  		-o $(srcdir)/$(IGEN_OPCODE_RULES) \
  		-k $(srcdir)/ppc-cache-rules \
! 		-i $(srcdir)/ppc-instructions \
  		-n icache.h    -hc tmp-icache.h \
  		-n icache.c    -c  tmp-icache.c \
  		-n semantics.h -hs tmp-semantics.h \
--- 464,470 ----
  	./igen	$(IGEN_FLAGS) \
  		-o $(srcdir)/$(IGEN_OPCODE_RULES) \
  		-k $(srcdir)/ppc-cache-rules \
! 		-I $(srcdir) -i $(srcdir)/ppc-instructions \
  		-n icache.h    -hc tmp-icache.h \
  		-n icache.c    -c  tmp-icache.c \
  		-n semantics.h -hs tmp-semantics.h \
Index: ppc/igen.c
===================================================================
RCS file: /cvs/src/src/sim/ppc/igen.c,v
retrieving revision 1.2
diff -p -r1.2 igen.c
*** igen.c	2001/12/14 00:22:12	1.2
--- igen.c	2002/01/04 04:42:19
*************** main(int argc,
*** 347,352 ****
--- 347,353 ----
    decode_table *decode_rules = NULL;
    filter *filters = NULL;
    insn_table *instructions = NULL;
+   table_include *includes = NULL;
    char *real_file_name = NULL;
    int is_header = 0;
    int ch;
*************** main(int argc,
*** 405,413 ****
      case 'E':
        generate_expanded_instructions = 1;
        break;
      case 'I':
!       icache_size = a2i(optarg);
!       code |= generate_with_icache;
        break;
      case 'N':
        generate_smp = a2i(optarg);
--- 406,454 ----
      case 'E':
        generate_expanded_instructions = 1;
        break;
+     case 'G':
+       {
+ 	int enable_p;
+ 	char *argp;
+ 	if (strncmp (optarg, "no-", strlen ("no-")) == 0)
+ 	  {
+ 	    argp = optarg + strlen ("no-");
+ 	    enable_p = 0;
+ 	  }
+ 	else if (strncmp (optarg, "!", strlen ("!")) == 0)
+ 	  {
+ 	    argp = optarg + strlen ("no-");
+ 	    enable_p = 0;
+ 	  }
+ 	else
+ 	  {
+ 	    argp = optarg;
+ 	    enable_p = 1;
+ 	  }
+         if (strncmp (argp, "gen-icache", strlen ("gen-icache")) == 0)
+           {
+             switch (argp[strlen ("gen-icache")])
+               {
+               case '=':
+ 	        icache_size = atoi (argp + strlen ("gen-icache") + 1);
+ 	        code |= generate_with_icache;
+                 break;
+               case '\0':
+ 	        code |= generate_with_icache;
+                 break;
+               default:
+                 error (NULL, "Expecting -Ggen-icache or -Ggen-icache=<N>\n");
+               }
+           }
+ 	}
      case 'I':
!       {
! 	table_include **dir = &includes;
! 	while ((*dir) != NULL)
! 	  dir = &(*dir)->next;
! 	(*dir) = ZALLOC (table_include);
! 	(*dir)->dir = strdup (optarg);
!       }
        break;
      case 'N':
        generate_smp = a2i(optarg);
*************** main(int argc,
*** 439,445 ****
  	fprintf(stderr, "Must specify decode and cache tables\n");
  	exit (1);
        }
!       instructions = load_insn_table(optarg, decode_rules, filters);
        fprintf(stderr, "\texpanding ...\n");
        insn_table_expand_insns(instructions);
        break;
--- 480,486 ----
  	fprintf(stderr, "Must specify decode and cache tables\n");
  	exit (1);
        }
!       instructions = load_insn_table(optarg, decode_rules, filters, includes);
        fprintf(stderr, "\texpanding ...\n");
        insn_table_expand_insns(instructions);
        break;
Index: ppc/ld-insn.c
===================================================================
RCS file: /cvs/src/src/sim/ppc/ld-insn.c,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 ld-insn.c
*** ld-insn.c	1999/04/16 01:35:11	1.1.1.1
--- ld-insn.c	2002/01/04 04:42:22
*************** parse_insn_format(table_entry *entry,
*** 191,196 ****
--- 191,214 ----
  }
  
  
+ void
+ parse_include_entry (table *file,
+                      table_entry *file_entry,
+ 		     filter *filters,
+ 		     table_include *includes)
+ {
+   /* parse the include file_entry */
+   if (file_entry->nr_fields < 4)
+     error ("Incorrect nr fields for include record\n");
+   /* process it */
+   if (!is_filtered_out(file_entry->fields[include_flags], filters))
+     {
+       table_push (file, includes,
+                 file_entry->fields[include_path],
+ 		file_entry->nr_fields, file_entry->nr_fields);
+     }
+ }
+ 
  static void
  model_table_insert(insn_table *table,
  		   table_entry *file_entry)
*************** insn_table_insert_insn(insn_table *table
*** 313,319 ****
  insn_table *
  load_insn_table(const char *file_name,
  		decode_table *decode_rules,
! 		filter *filters)
  {
    table *file = table_open(file_name, nr_insn_table_fields, nr_insn_model_table_fields);
    insn_table *table = ZALLOC(insn_table);
--- 331,338 ----
  insn_table *
  load_insn_table(const char *file_name,
  		decode_table *decode_rules,
! 		filter *filters,
! 		table_include *includes)
  {
    table *file = table_open(file_name, nr_insn_table_fields, nr_insn_model_table_fields);
    insn_table *table = ZALLOC(insn_table);
*************** load_insn_table(const char *file_name,
*** 343,348 ****
--- 362,371 ----
      else if (it_is("model-data", file_entry->fields[insn_flags])) {
        model_table_insert_specific(table, file_entry, &model_data, &last_model_data);
      }
+     else if (it_is("include", file_entry->fields[insn_form])
+              && !is_filtered_out(file_entry->fields[insn_flags], filters)) {
+       parse_include_entry (file, file_entry, filters, includes);
+     }
      else {
        insn_fields *fields;
        /* skip instructions that aren't relevant to the mode */
*************** main(int argc, char **argv)
*** 915,921 ****
    hi_bit_nr = a2i(argv[2]);
    ASSERT(hi_bit_nr < insn_bit_size);
    decode_rules = load_decode_table(argv[3], hi_bit_nr);
!   instructions = load_insn_table(argv[4], decode_rules, filters);
    insn_table_expand_insns(instructions);
  
    dump_insn_table(instructions, 0, -1);
--- 938,944 ----
    hi_bit_nr = a2i(argv[2]);
    ASSERT(hi_bit_nr < insn_bit_size);
    decode_rules = load_decode_table(argv[3], hi_bit_nr);
!   instructions = load_insn_table(argv[4], decode_rules, filters, NULL);
    insn_table_expand_insns(instructions);
  
    dump_insn_table(instructions, 0, -1);
Index: ppc/ld-insn.h
===================================================================
RCS file: /cvs/src/src/sim/ppc/ld-insn.h,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 ld-insn.h
*** ld-insn.h	1999/04/16 01:35:11	1.1.1.1
--- ld-insn.h	2002/01/04 04:42:22
*************** typedef enum {
*** 134,139 ****
--- 134,144 ----
    model_default = insn_comment,
  } model_table_fields;
  
+ typedef enum {
+   include_flags = insn_flags,
+   include_path = insn_name,
+ } model_include_fields;
+ 
  typedef struct _insn insn;
  struct _insn {
    table_entry *file_entry;
*************** typedef enum {
*** 183,189 ****
  extern insn_table *load_insn_table
  (const char *file_name,
   decode_table *decode_rules,
!  filter *filters);
  
  model *models;
  model *last_model;
--- 188,195 ----
  extern insn_table *load_insn_table
  (const char *file_name,
   decode_table *decode_rules,
!  filter *filters,
!  table_include *includes);
  
  model *models;
  model *last_model;
Index: ppc/misc.h
===================================================================
RCS file: /cvs/src/src/sim/ppc/misc.h,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 misc.h
*** misc.h	1999/04/16 01:35:11	1.1.1.1
--- misc.h	2002/01/04 04:42:22
*************** do { \
*** 58,63 ****
--- 58,64 ----
  } while (0)
  
  #define ZALLOC(TYPE) (TYPE*)zalloc(sizeof(TYPE))
+ #define NZALLOC(TYPE,N) ((TYPE*) zalloc (sizeof(TYPE) * (N)))
  
  extern void *zalloc
  (long size);
Index: ppc/ppc-instructions
===================================================================
RCS file: /cvs/src/src/sim/ppc/ppc-instructions,v
retrieving revision 1.3
diff -p -r1.3 ppc-instructions
*** ppc-instructions	2000/10/24 16:16:43	1.3
--- ppc-instructions	2002/01/04 04:42:22
***************
*** 150,156 ****
--- 150,158 ----
  	  unsigned32 int_busy;				/* int registers that are busy */
  	  unsigned32 fp_busy;				/* floating point registers that are busy */
  	  unsigned32 cr_fpscr_busy;			/* CR/FPSCR registers that are busy */
+ 	  unsigned32 vr_busy;				/* AltiVec registers that are busy */
  	  signed16 spr_busy;				/* SPR register that is busy or PPC_NO_SPR */
+ 	  signed16 vscr_busy;				/* AltiVec status register busy */
  	  signed16 issue;				/* # of cycles until unit can accept another insn */
  	  signed16 done;				/* # of cycles until insn is done */
  	  signed16 nr_writebacks;			/* # of registers this unit writes back */
***************
*** 179,186 ****
--- 181,190 ----
  	  int max_nr_writebacks;			/* max # of writeback slots available */
  	  unsigned32 int_busy;				/* int registers that are busy */
  	  unsigned32 fp_busy;				/* floating point registers that are busy */
+ 	  unsigned32 vr_busy;				/* AltiVec registers that are busy */
  	  unsigned32 cr_fpscr_busy;			/* CR/FPSCR registers that are busy */
  	  unsigned8 spr_busy[nr_of_sprs];		/* SPR registers that are busy */
+ 	  unsigned8 vscr_busy;				/* AltiVec SC register busy */
  	  unsigned8 busy[nr_ppc_function_units];	/* whether a function is busy or not */
  	};
  
*************** void::model-static::model_trace_release:
*** 273,278 ****
--- 277,291 ----
  	}
  	if (busy->spr_busy != PPC_NO_SPR)
  	  TRACE(trace_model, ("Register %s is now available.\n", spr_name(busy->spr_busy)));
+ 	if (busy->vr_busy) {
+ 	  for(i = 0; i < 32; i++) {
+ 	    if (((1 << i) & busy->vr_busy) != 0) {
+ 	      TRACE(trace_model, ("Register v%d is now available.\n", i));
+ 	    }
+ 	  }
+ 	}
+ 	if (busy->vscr_busy)
+ 	  TRACE(trace_model, ("VSCR Register is now available.\n", spr_name(busy->spr_busy)));
  
  # Trace making registers busy
  void::model-static::model_trace_make_busy:model_data *model_ptr, unsigned32 int_mask, unsigned32 fp_mask, unsigned32 cr_mask
*************** void::model-internal::model_new_cycle:mo
*** 351,356 ****
--- 364,371 ----
  	      model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy;
  	      if (cur_busy->spr_busy != PPC_NO_SPR)
  		model_ptr->spr_busy[cur_busy->spr_busy] = 0;
+ 	      model_ptr->vr_busy &= ~cur_busy->vr_busy;
+ 	      model_ptr->vscr_busy = ~cur_busy->vscr_busy;
  
  	      if (WITH_TRACE && ppc_trace[trace_model])
  		model_trace_release(model_ptr, cur_busy);
*************** model_busy *::model-internal::model_make
*** 407,412 ****
--- 422,429 ----
  	  busy->fp_busy = 0;
  	  busy->cr_fpscr_busy = 0;
  	  busy->nr_writebacks = 0;
+ 	  busy->vr_busy = 0;
+ 	  busy->vscr_busy = 0;
  	}
  
  	busy->unit = unit;
*************** void::function::invalid_zero_divide_oper
*** 4925,4927 ****
--- 4942,4946 ----
  0.31,6.RT,11.RA,16.RB,21.310,31./:X:earwax::External Control In Word Indexed
  
  0.31,6.RS,11.RA,16.RB,21.438,31./:X:earwax::External Control Out Word Indexed
+ 
+ :include:::altivec-instructions
Index: ppc/table.c
===================================================================
RCS file: /cvs/src/src/sim/ppc/table.c,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 table.c
*** table.c	1999/04/16 01:35:11	1.1.1.1
--- table.c	2002/01/04 04:42:22
***************
*** 38,44 ****
  #include <stdlib.h>
  #endif
  
! struct _table {
    size_t size;
    char *buffer;
    char *pos;
--- 38,45 ----
  #include <stdlib.h>
  #endif
  
! typedef struct _open_table open_table;
! struct _open_table {
    size_t size;
    char *buffer;
    char *pos;
*************** struct _table {
*** 46,77 ****
    int nr_fields;
    int nr_model_fields;
    char *file_name;
  };
  
! extern table *
! table_open(const char *file_name,
! 	   int nr_fields,
! 	   int nr_model_fields)
  {
    int fd;
    struct stat stat_buf;
!   table *file;
    int nr;
  
    /* create a file descriptor */
!   file = ZALLOC(table);
    ASSERT(file != NULL);
    file->nr_fields = nr_fields;
    file->nr_model_fields = nr_model_fields;
! 
!   /* save the file name */
!   file->file_name = (char*)zalloc(strlen(file_name) + 1);
!   ASSERT(file->file_name != NULL);
!   strcpy(file->file_name, file_name);
! 
!   /* open the file */
!   fd = open(file->file_name, O_RDONLY, 0);
!   ASSERT(fd >= 0);
  
    /* determine the size */
    if (fstat(fd, &stat_buf) < 0) {
--- 47,116 ----
    int nr_fields;
    int nr_model_fields;
    char *file_name;
+   open_table *parent;
+   table *root;
+ };
+ struct _table {
+   open_table *current;
  };
  
! void
! table_push (table *root,
! 	    table_include *includes,
! 	    const char *file_name,
! 	    int nr_fields,
! 	    int nr_model_fields)
! 
  {
    int fd;
    struct stat stat_buf;
!   open_table *file;
!   table_include dummy;
!   table_include *include = &dummy;
    int nr;
  
+   /* dummy up a search of this directory */
+   dummy.next = includes;
+   dummy.dir = "";
+ 
    /* create a file descriptor */
!   file = ZALLOC (open_table);
    ASSERT(file != NULL);
    file->nr_fields = nr_fields;
    file->nr_model_fields = nr_model_fields;
!   file->root = root;
!   file->parent = root->current;
!   root->current = file;
!   
!   while (1)
!     {
!       /* save the file name */
!       char *dup_name = NZALLOC (char, strlen (include->dir) + strlen (file_name) + 2);
!       if (dup_name == NULL)
! 	{
! 	  perror (file_name);
! 	  exit (1);
! 	}
!       if (include->dir[0] != '\0')
! 	{
! 	  strcat (dup_name, include->dir);
! 	  strcat (dup_name, "/");
! 	}
!       strcat (dup_name, file_name);
!       file->file_name = dup_name;
!       /* open the file */
!       fd = open (dup_name, O_RDONLY, 0);
!       if (fd >= 0)
! 	break;
!       /* zfree (dup_name); */
!       if (include->next == NULL)
! 	{
! 	  error ("Problem opening file `%s'\n", file_name);
! 	  perror (file_name);
! 	  exit (1);
! 	}
!       include = include->next;
!   }
  
    /* determine the size */
    if (fstat(fd, &stat_buf) < 0) {
*************** table_open(const char *file_name,
*** 102,119 ****
  
    /* done */
    close(fd);
-   return file;
  }
  
  
  extern table_entry *
! table_entry_read(table *file)
  {
    int field;
    table_entry *entry;
  
    /* skip comments/blanks */
    while(1) {
      /* leading white space */
      while (*file->pos != '\0'
  	   && *file->pos != '\n'
--- 141,187 ----
  
    /* done */
    close(fd);
  }
  
+ extern table *
+ table_open(const char *file_name,
+ 	   int nr_fields,
+ 	   int nr_model_fields)
+ {
+   table *root;
+ 
+   /* create a file descriptor */
+   root = ZALLOC (table);
+   if (root == NULL)
+     {
+       perror (file_name);
+       exit (1);
+     }
+ 
+   table_push (root, NULL, file_name, nr_fields, nr_model_fields);
+   return root;
+ }
  
  extern table_entry *
! table_entry_read(table *root)
  {
+   open_table *file = root->current;
    int field;
    table_entry *entry;
  
    /* skip comments/blanks */
    while(1) {
+     /* end-of-file? */
+     while (*file->pos == '\0')
+       {
+         if (file->parent != NULL)
+           {
+             file = file->parent;
+             root->current = file;
+           }
+         else
+           return NULL;
+       }
      /* leading white space */
      while (*file->pos != '\0'
  	   && *file->pos != '\n'
*************** table_entry_read(table *file)
*** 133,140 ****
      else
        break;
    }
-   if (*file->pos == '\0')
-     return NULL;
  
    /* create this new entry */
    entry = (table_entry*)zalloc(sizeof(table_entry)
--- 201,206 ----
Index: ppc/table.h
===================================================================
RCS file: /cvs/src/src/sim/ppc/table.h,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 table.h
*** table.h	1999/04/16 01:35:11	1.1.1.1
--- table.h	2002/01/04 04:42:22
*************** struct _table_entry {
*** 42,47 ****
--- 42,54 ----
    char *fields[0];	 /* User defined */
  };
  
+ /* List of directories to search when opening a pushed file.  Current
+    directory is always searched first */
+ typedef struct _table_include table_include;
+ struct _table_include {
+   char *dir;
+   table_include *next;
+ };
  
  extern table *table_open
  (const char *file_name,
*************** extern table *table_open
*** 50,55 ****
--- 57,72 ----
  
  extern table_entry *table_entry_read
  (table *file);
+ 
+ /* Push the the state of the current file and open FILE_NAME.  When
+    the end of FILE_NAME is reached, return to the pushed file */
+ 
+ extern void table_push
+ (table *file,
+  table_include *search,
+  const char *file_name,
+  int nr_fields,
+  int nr_model_fields);
  
  extern void dump_table_entry
  (table_entry *entry,



More information about the Gdb-patches mailing list