/*  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*)0x%x\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 0x%x)\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
