void
print_semantic_body(lf *file,
		    insn *instruction,
		    insn_bits *expanded_bits,
		    opcode_field *opcodes)
{
  print_itrace(file, instruction->file_entry, 0/*put_value_in_cache*/);

  /* validate the instruction, if a cache this has already been done */
  if (!(code & generate_with_icache))
    print_idecode_validate(file, instruction, opcodes);

  /* generate the profiling call - this is delayed until after the
     instruction has been verified */
  lf_printf(file, "\n");
  lf_printf(file, "/* monitoring: */\n");
  lf_printf(file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE) {\n");
  lf_printf(file, "  mon_issue(");
  print_function_name(file,
		      instruction->file_entry->fields[insn_name],
		      NULL,
		      function_name_prefix_itable);
  lf_printf(file, ", processor, cia);\n");
  lf_printf(file, "}\n");

  /* generate the code (or at least something */
  lf_printf(file, "\n");
  lf_printf(file, "/* semantics: */\n");
  lf_printf(file, "nia = cia + %d;\n", insn_bit_size / 8);
  if (instruction->file_entry->annex != NULL) {
    /* true code */
    table_entry_print_cpp_line_nr(file, instruction->file_entry);
    lf_printf(file, "{\n");
    lf_indent(file, +2);
    lf_print__c_code(file, instruction->file_entry->annex);
    lf_indent(file, -2);
    lf_printf(file, "}\n");
    lf_print__internal_reference(file);
  }
  else if (it_is("nop", instruction->file_entry->fields[insn_flags])) {
    lf_print__internal_reference(file);
  }
  else {
    /* abort so it is implemented now */
    table_entry_print_cpp_line_nr(file, instruction->file_entry);
    lf_putstr(file, "error(\"%s:%d:0x%08lx:%s unimplemented\\n\",\n");
    lf_printf(file, "      itable[MY_INDEX].file, itable[MY_INDEX].line_nr, (long)cia, itable[MY_INDEX].name);\n");
    lf_print__internal_reference(file);
  }
}
static void
model_c_function(insn_table *table,
		 lf *file,
		 table_entry *function,
		 const char *prefix)
{
  if (function->fields[function_type] == NULL
      || function->fields[function_type][0] == '\0') {
    error("Model function return type not specified for %s", function->fields[function_name]);
  }
  else {
    lf_printf(file, "\n");
    lf_print_function_type(file, function->fields[function_type], prefix, "\n");
    lf_printf(file, "%s(%s)\n",
	      function->fields[function_name],
	      function->fields[function_param]);
  }
  table_entry_print_cpp_line_nr(file, function);
  lf_printf(file, "{\n");
  if (function->annex) {
    lf_indent(file, +2);
    lf_print__c_code(file, function->annex);
    lf_indent(file, -2);
  }
  lf_printf(file, "}\n");
  lf_print__internal_reference(file);
  lf_printf(file, "\n");
}
static void
model_c_or_h_data (insn_table *table, lf *file, table_entry *data)
{
  if (data->annex)
    {
      table_entry_print_cpp_line_nr (file, data->annex_line);
      lf_print__c_code (file, data->annex);
      lf_print__internal_reference (file);
      lf_printf (file, "\n");
    }
}
Beispiel #4
0
void
print_itrace(lf *file,
	     table_entry *file_entry,
	     int idecode)
{
  lf_print__external_reference(file, file_entry->line_nr, file_entry->file_name);
  lf_printf(file, "ITRACE(trace_%s, (\"%s %s\\n\"));\n",
	    (idecode ? "idecode" : "semantics"),
	    (idecode ? "idecode" : "semantics"),
	    file_entry->fields[insn_name]);
  lf_print__internal_reference(file);
}
Beispiel #5
0
void
print_icache_internal_function_definition(insn_table *table,
					  lf *file,
					  void *data,
					  table_entry *function)
{
  ASSERT((code & generate_with_icache) != 0);
  if (it_is("internal", function->fields[insn_flags])) {
    lf_printf(file, "\n");
    lf_print_function_type(file, ICACHE_FUNCTION_TYPE, "INLINE_ICACHE",
			   "\n");
    print_function_name(file,
			function->fields[insn_name],
			NULL,
			function_name_prefix_icache);
    lf_printf(file, "\n(%s)\n", ICACHE_FUNCTION_FORMAL);
    lf_printf(file, "{\n");
    lf_indent(file, +2);
    lf_printf(file, "/* semantic routine */\n");
    table_entry_print_cpp_line_nr(file, function);
    if ((code & generate_with_semantic_icache)) {
      lf_print__c_code(file, function->annex);
      lf_printf(file, "error(\"Internal function must longjump\\n\");\n");
      lf_printf(file, "return 0;\n");
    }
    else {
      lf_printf(file, "return ");
      print_function_name(file,
			  function->fields[insn_name],
			  NULL,
			  function_name_prefix_semantics);
      lf_printf(file, ";\n");
    }
    
    lf_print__internal_reference(file);
    lf_indent(file, -2);
    lf_printf(file, "}\n");
  }
}
Beispiel #6
0
static void
support_c_function(insn_table *table,
		   lf *file,
		   void *data,
		   table_entry *function)
{
  ASSERT(function->fields[function_type] != NULL);
  print_support_function_name(file,
			      function,
			      1/*!is_definition*/);
  table_entry_print_cpp_line_nr(file, function);
  lf_printf(file, "{\n");
  lf_indent(file, +2);
  lf_print__c_code(file, function->annex);
  if (it_is("internal", function->fields[insn_flags])) {
    lf_printf(file, "error(\"Internal function must longjump\\n\");\n");
    lf_printf(file, "return 0;\n");
  }
  lf_indent(file, -2);
  lf_printf(file, "}\n");
  lf_print__internal_reference(file);
  lf_printf(file, "\n");
}
Beispiel #7
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);
  }
}