/*  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"
#include "dumpf.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
