diff options
author | Andrew Cagney <cagney@redhat.com> | 1997-02-21 02:49:21 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 1997-02-21 02:49:21 +0000 |
commit | a4c97499d90ab83a01d80d4c3df2455a73486e3c (patch) | |
tree | 9a52d25e56a06fec8fa103dbeb4d7477b1f5d23c /sim/igen/misc.c | |
parent | 317df3b530276f2acbdf8950d1d9b76deb83753c (diff) | |
download | gdb-a4c97499d90ab83a01d80d4c3df2455a73486e3c.zip gdb-a4c97499d90ab83a01d80d4c3df2455a73486e3c.tar.gz gdb-a4c97499d90ab83a01d80d4c3df2455a73486e3c.tar.bz2 |
Instruction decode generator taken from the PowerPC simulator
and being made more generic.
Diffstat (limited to 'sim/igen/misc.c')
-rw-r--r-- | sim/igen/misc.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/sim/igen/misc.c b/sim/igen/misc.c new file mode 100644 index 0000000..660570c --- /dev/null +++ b/sim/igen/misc.c @@ -0,0 +1,226 @@ +/* This file is part of the program psim. + + Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + + +#include <stdio.h> +#include <stdarg.h> +#include <ctype.h> + +#include "config.h" +#include "misc.h" + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +#ifdef HAVE_STRING_H +#include <string.h> +#else +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif +#endif + +void +error (char *msg, ...) +{ + va_list ap; + va_start(ap, msg); + vprintf(msg, ap); + va_end(ap); + exit (1); +} + +void * +zalloc(long size) +{ + void *memory = malloc(size); + if (memory == NULL) + error("zalloc failed\n"); + memset(memory, 0, size); + return memory; +} + +void +dumpf (int indent, char *msg, ...) +{ + va_list ap; + for (; indent > 0; indent--) + printf(" "); + va_start(ap, msg); + vprintf(msg, ap); + va_end(ap); +} + + +unsigned long long +a2i(const char *a) +{ + int neg = 0; + int base = 10; + unsigned long long num = 0; + int looping; + + while (isspace (*a)) + a++; + + if (*a == '-') { + neg = 1; + a++; + } + + if (*a == '0') { + if (a[1] == 'x' || a[1] == 'X') { + a += 2; + base = 16; + } else if (a[1] == 'b' || a[1] == 'b') { + a += 2; + base = 2; + } + else + base = 8; + } + + looping = 1; + while (looping) { + int ch = *a++; + + switch (base) { + default: + looping = 0; + break; + + case 2: + if (ch >= '0' && ch <= '1') { + num = (num * 2) + (ch - '0'); + } else { + looping = 0; + } + break; + + case 10: + if (ch >= '0' && ch <= '9') { + num = (num * 10) + (ch - '0'); + } else { + looping = 0; + } + break; + + case 8: + if (ch >= '0' && ch <= '7') { + num = (num * 8) + (ch - '0'); + } else { + looping = 0; + } + break; + + case 16: + if (ch >= '0' && ch <= '9') { + num = (num * 16) + (ch - '0'); + } else if (ch >= 'a' && ch <= 'f') { + num = (num * 16) + (ch - 'a' + 10); + } else if (ch >= 'A' && ch <= 'F') { + num = (num * 16) + (ch - 'A' + 10); + } else { + looping = 0; + } + break; + } + } + + if (neg) + num = - num; + + return num; +} + +unsigned +target_a2i(int ms_bit_nr, + const char *a) +{ + if (ms_bit_nr) + return (ms_bit_nr - a2i(a)); + else + return a2i(a); +} + +unsigned +i2target(int ms_bit_nr, + unsigned bit) +{ + if (ms_bit_nr) + return ms_bit_nr - bit; + else + return bit; +} + + +int +name2i(const char *names, + const name_map *map) +{ + const name_map *curr; + const char *name = names; + while (*name != '\0') { + /* find our name */ + char *end = strchr(name, ','); + char *next; + int len; + if (end == NULL) { + end = strchr(name, '\0'); + next = end; + } + else { + next = end + 1; + } + len = end - name; + /* look it up */ + curr = map; + while (curr->name != NULL) { + if (strncmp(curr->name, name, len) == 0 + && strlen(curr->name) == len) + return curr->i; + curr++; + } + name = next; + } + /* nothing found, possibly return a default */ + curr = map; + while (curr->name != NULL) + curr++; + if (curr->i >= 0) + return curr->i; + else + error("%s contains no valid names\n", names); + return 0; +} + +const char * +i2name(const int i, + const name_map *map) +{ + while (map->name != NULL) { + if (map->i == i) + return map->name; + map++; + } + error("map lookup failed for %d\n", i); + return NULL; +} |