Esempio n. 1
0
void
print_icache_body(lf *file,
		  insn *instruction,
		  insn_bits *expanded_bits,
		  cache_table *cache_rules,
		  icache_decl_type what_to_declare,
		  icache_body_type what_to_do)
{
  insn_field *cur_field;
  
  /* extract instruction fields */
  lf_printf(file, "/* extraction: %s ",
	    instruction->file_entry->fields[insn_format]);
  switch (what_to_declare) {
  case define_variables:
    lf_printf(file, "#define");
    break;
  case declare_variables:
    lf_printf(file, "declare");
    break;
  case undef_variables:
    lf_printf(file, "#undef");
    break;
  }
  lf_printf(file, " ");
  switch (what_to_do) {
  case get_values_from_icache:
    lf_printf(file, "get-values-from-icache");
    break;
  case put_values_in_icache:
    lf_printf(file, "put-values-in-icache");
    break;
  case both_values_and_icache:
    lf_printf(file, "get-values-from-icache|put-values-in-icache");
    break;
  case do_not_use_icache:
    lf_printf(file, "do-not-use-icache");
    break;
  }
  lf_printf(file, " */\n");
  
  for (cur_field = instruction->fields->first;
       cur_field->first < insn_bit_size;
       cur_field = cur_field->next) {
    if (cur_field->is_string) {
      insn_bits *bits;
      int found_rule = 0;
      /* find any corresponding value */
      for (bits = expanded_bits;
	   bits != NULL;
	   bits = bits->last) {
	if (bits->field == cur_field)
	  break;
      }
      /* try the cache rule table for what to do */
      {
	cache_table *cache_rule;
	for (cache_rule = cache_rules;
	     cache_rule != NULL;
	     cache_rule = cache_rule->next) {
	  if (strcmp(cur_field->val_string, cache_rule->field_name) == 0) {
	    found_rule = 1;
	    if (cache_rule->type == scratch_value
		&& ((what_to_do & put_values_in_icache)
		    || what_to_do == do_not_use_icache))
	      print_icache_extraction(file,
				      instruction,
				      cache_rule->derived_name,
				      cache_rule->type_def,
				      cache_rule->expression,
				      cache_rule->field_name,
				      cache_rule->file_entry->file_name,
				      cache_rule->file_entry->line_nr,
				      cur_field,
				      bits,
				      what_to_declare,
				      do_not_use_icache,
				      "icache scratch");
	    else if (cache_rule->type == compute_value
		     && ((what_to_do & get_values_from_icache)
			 || what_to_do == do_not_use_icache))
	      print_icache_extraction(file,
				      instruction,
				      cache_rule->derived_name,
				      cache_rule->type_def,
				      cache_rule->expression,
				      cache_rule->field_name,
				      cache_rule->file_entry->file_name,
				      cache_rule->file_entry->line_nr,
				      cur_field,
				      bits,
				      what_to_declare,
				      do_not_use_icache,
				      "semantic compute");
	    else if (cache_rule->type == cache_value
		     && ((what_to_declare != undef_variables)
			 || !(what_to_do & put_values_in_icache)))
	      print_icache_extraction(file,
				      instruction,
				      cache_rule->derived_name,
				      cache_rule->type_def,
				      cache_rule->expression,
				      cache_rule->field_name,
				      cache_rule->file_entry->file_name,
				      cache_rule->file_entry->line_nr,
				      cur_field,
				      bits,
				      ((what_to_do & put_values_in_icache)
				       ? declare_variables
				       : what_to_declare),
				      what_to_do,
				      "in icache");
	  }
	}
      }
      /* No rule at all, assume that this is needed in the semantic
         function (when values are extracted from the icache) and
         hence must be put into the cache */
      if (found_rule == 0
	  && ((what_to_declare != undef_variables)
	      || !(what_to_do & put_values_in_icache)))
	print_icache_extraction(file,
				instruction,
				cur_field->val_string,
				NULL, NULL, NULL, /* type, exp, orig */
				instruction->file_entry->file_name,
				instruction->file_entry->line_nr,
				cur_field,
				bits,
				((what_to_do & put_values_in_icache)
				 ? declare_variables
				 : what_to_declare),
				what_to_do,
				"default in icache");
      /* any thing else ... */
    }
  }

  lf_print__internal_reference(file);

  if ((code & generate_with_insn_in_icache)) {
    lf_printf(file, "\n");
    print_icache_extraction(file,
			    instruction,
			    "insn",
			    "instruction_word",
			    "instruction",
			    NULL, /* origin */
			    NULL, 0, /* file_name & line_nr */
			    NULL, NULL,
			    what_to_declare,
			    what_to_do,
			    NULL);
  }
}
Esempio n. 2
0
File: gen-icache.c Progetto: 5kg/gdb
void
print_icache_body (lf *file,
		   insn_entry * instruction,
		   opcode_bits *expanded_bits,
		   cache_entry *cache_rules,
		   icache_decl_type what_to_declare,
		   icache_body_type what_to_do, int nr_prefetched_words)
{
  /* extract instruction fields */
  lf_printf (file, "/* Extraction: %s\n", instruction->name);
  lf_printf (file, "     ");
  switch (what_to_declare)
    {
    case define_variables:
      lf_printf (file, "#define");
      break;
    case declare_variables:
      lf_printf (file, "declare");
      break;
    case undef_variables:
      lf_printf (file, "#undef");
      break;
    }
  lf_printf (file, " ");
  switch (what_to_do)
    {
    case get_values_from_icache:
      lf_printf (file, "get-values-from-icache");
      break;
    case put_values_in_icache:
      lf_printf (file, "put-values-in-icache");
      break;
    case both_values_and_icache:
      lf_printf (file, "get-values-from-icache|put-values-in-icache");
      break;
    case do_not_use_icache:
      lf_printf (file, "do-not-use-icache");
      break;
    }
  lf_printf (file, "\n     ");
  print_insn_words (file, instruction);
  lf_printf (file, " */\n");

  /* pass zero - fetch from memory any missing instructions.

     Some of the instructions will have already been fetched (in the
     instruction array), others will still need fetching. */
  switch (what_to_do)
    {
    case get_values_from_icache:
      break;
    case put_values_in_icache:
    case both_values_and_icache:
    case do_not_use_icache:
      {
	int word_nr;
	switch (what_to_declare)
	  {
	  case undef_variables:
	    break;
	  case define_variables:
	  case declare_variables:
	    for (word_nr = nr_prefetched_words;
		 word_nr < instruction->nr_words; word_nr++)
	      {
		/* FIXME - should be using print_icache_extraction? */
		lf_printf (file,
			   "%sinstruction_word instruction_%d UNUSED = ",
			   options.module.global.prefix.l, word_nr);
		lf_printf (file, "IMEM%d_IMMED (cia, %d)",
			   options.insn_bit_size, word_nr);
		lf_printf (file, ";\n");
	      }
	  }
      }
    }

  /* if putting the instruction words in the cache, define references
     for them */
  if (options.gen.insn_in_icache)
    {
      /* FIXME: is the instruction_word type correct? */
      print_icache_extraction (file, instruction->format_name, cache_value, "insn",	/* name */
			       "instruction_word",	/* type */
			       "instruction",	/* expression */
			       NULL,	/* origin */
			       NULL,	/* line */
			       NULL, NULL, what_to_declare, what_to_do);
    }
  lf_printf (file, "\n");

  /* pass one - process instruction fields.

     If there is no cache rule, the default is to enter the field into
     the cache */
  {
    insn_word_entry *word;
    for (word = instruction->words; word != NULL; word = word->next)
      {
	insn_field_entry *cur_field;
	for (cur_field = word->first;
	     cur_field->first < options.insn_bit_size;
	     cur_field = cur_field->next)
	  {
	    /* Always expand named fields (even if constant), so
	       references are valid.  */
	    if (cur_field->type == insn_field_string)
	      {
		cache_entry *cache_rule;
		cache_entry_type value_type = cache_value;
		line_ref *value_line = instruction->line;
		/* check the cache table to see if it contains a rule
		   overriding the default cache action for an
		   instruction field */
		for (cache_rule = cache_rules;
		     cache_rule != NULL; cache_rule = cache_rule->next)
		  {
		    if (filter_is_subset (instruction->field_names,
					  cache_rule->original_fields)
			&& strcmp (cache_rule->name,
				   cur_field->val_string) == 0)
		      {
			value_type = cache_rule->entry_type;
			value_line = cache_rule->line;
			if (value_type == compute_value)
			  {
			    options.warning (cache_rule->line,
					     "instruction field of type `compute' changed to `cache'\n");
			    cache_rule->entry_type = cache_value;
			  }
			break;
		      }
		  }
		/* Define an entry for the field within the
		   instruction */
		print_icache_extraction (file, instruction->format_name, value_type, cur_field->val_string,	/* name */
					 NULL,	/* type */
					 NULL,	/* expression */
					 cur_field->val_string,	/* insn field */
					 value_line,
					 cur_field,
					 expanded_bits,
					 what_to_declare, what_to_do);
	      }
	  }
      }
  }

  /* pass two - any cache fields not processed above */
  {
    cache_entry *cache_rule;
    for (cache_rule = cache_rules;
	 cache_rule != NULL; cache_rule = cache_rule->next)
      {
	if (filter_is_subset (instruction->field_names,
			      cache_rule->original_fields)
	    && !filter_is_member (instruction->field_names, cache_rule->name))
	  {
	    char *single_field =
	      filter_next (cache_rule->original_fields, "");
	    if (filter_next (cache_rule->original_fields, single_field) !=
		NULL)
	      single_field = NULL;
	    print_icache_extraction (file, instruction->format_name, cache_rule->entry_type, cache_rule->name, cache_rule->type, cache_rule->expression, single_field, cache_rule->line, NULL,	/* cur_field */
				     expanded_bits,
				     what_to_declare, what_to_do);
	  }
      }
  }

  lf_print__internal_ref (file);
}