diff options
Diffstat (limited to 'sim/igen/misc.c')
-rw-r--r-- | sim/igen/misc.c | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/sim/igen/misc.c b/sim/igen/misc.c new file mode 100644 index 00000000000..8490132f32e --- /dev/null +++ b/sim/igen/misc.c @@ -0,0 +1,284 @@ +/* This file is part of the program psim. + + Copyright (C) 1994-1997, 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 + +/* NB: Because warning and error can be interchanged, neither append a + trailing '\n' */ + +void +error (const line_ref *line, + char *msg, + ...) +{ + va_list ap; + if (line != NULL) + fprintf (stderr, "%s:%d: ", line->file_name, line->line_nr); + va_start (ap, msg); + vfprintf (stderr, msg, ap); + va_end (ap); + exit (1); +} + +void +warning (const line_ref *line, + char *msg, + ...) +{ + va_list ap; + if (line != NULL) + fprintf (stderr, "%s:%d: warning: ", line->file_name, line->line_nr); + va_start (ap, msg); + vfprintf (stderr, msg, ap); + va_end (ap); +} + +void +notify (const line_ref *line, + char *msg, + ...) +{ + va_list ap; + if (line != NULL) + fprintf (stdout, "%s %d: info: ", line->file_name, line->line_nr); + va_start(ap, msg); + vfprintf (stdout, msg, ap); + va_end(ap); +} + +void * +zalloc(long size) +{ + void *memory = malloc(size); + if (memory == NULL) + ERROR ("zalloc failed"); + memset(memory, 0, size); + return memory; +} + + +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 (strcmp (a, "true") == 0 + || strcmp (a, "TRUE") == 0) + return 1; + + if (strcmp (a, "false") == 0 + || strcmp (a, "false") == 0) + return 0; + + 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; + unsigned 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 (NULL, "%s contains no valid names", 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 (NULL, "map lookup failed for %d\n", i); + return NULL; +} |