[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