/*  This file is part of the program psim.

    Copyright 1994, 1995, 1996, 1997, 2003 Andrew Cagney

    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 3 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, see <http://www.gnu.org/licenses/>.
 
    */


#include "misc.h"
#include "lf.h"
#include "table.h"
#include "ld-cache.h"


enum {
  ca_type,
  ca_field_name,
  ca_derived_name,
  ca_type_def,
  ca_expression,
  nr_cache_rule_fields,
};

static const name_map cache_type_map[] = {
  { "cache", cache_value },
  { "compute", compute_value },
  { "scratch", scratch_value },
  { NULL, 0 },
};


void
append_cache_rule (cache_table **table, const char *type,
		   const char *field_name, const char *derived_name,
		   const char *type_def, const char *expression,
		   table_entry *file_entry)
{
  while ((*table) != NULL)
    table = &(*table)->next;
  (*table) = ZALLOC(cache_table);
  (*table)->type = name2i(type, cache_type_map);
  (*table)->field_name = field_name;
  (*table)->derived_name = derived_name;
  (*table)->type_def = (strlen(type_def) > 0 ? type_def : NULL);
  (*table)->expression = (strlen(expression) > 0 ? expression : NULL);
  (*table)->file_entry = file_entry;
  (*table)->next = NULL;
}


cache_table *
load_cache_table(const char *file_name,
		 int hi_bit_nr)
{
  table *file = table_open(file_name, nr_cache_rule_fields, 0);
  table_entry *entry;
  cache_table *table = NULL;
  cache_table **curr_rule = &table;
  while ((entry = table_entry_read(file)) != NULL) {
    append_cache_rule (curr_rule, entry->fields[ca_type],
		       entry->fields[ca_field_name],
		       entry->fields[ca_derived_name],
		       entry->fields[ca_type_def],
		       entry->fields[ca_expression],
		       entry);
    curr_rule = &(*curr_rule)->next;
  }
  return table;
}



#ifdef MAIN

static void
dump_cache_rule(cache_table* rule,
		int indent)
{
  dumpf(indent, "((cache_table*)%p\n", rule);
  dumpf(indent, " (type %s)\n", i2name(rule->type, cache_type_map));
  dumpf(indent, " (field_name \"%s\")\n", rule->field_name);
  dumpf(indent, " (derived_name \"%s\")\n", rule->derived_name);
  dumpf(indent, " (type-def \"%s\")\n", rule->type_def);
  dumpf(indent, " (expression \"%s\")\n", rule->expression);
  dumpf(indent, " (next %p)\n", rule->next);
  dumpf(indent, " )\n");
}


static void
dump_cache_rules(cache_table* rule,
		 int indent)
{
  while (rule) {
    dump_cache_rule(rule, indent);
    rule = rule->next;
  }
}


int
main(int argc, char **argv)
{
  cache_table *rules;
  if (argc != 3)
    error("Usage: cache <cache-file> <hi-bit-nr>\n");
  rules = load_cache_table(argv[1], a2i(argv[2]));
  dump_cache_rules(rules, 0);
  return 0;
}
#endif
