Beispiel #1
0
void
print_icache_internal_function_definition (lf *file,
					   function_entry * function,
					   void *data)
{
  ASSERT (options.gen.icache);
  if (function->is_internal)
    {
      lf_printf (file, "\n");
      lf_print__function_type_function (file, print_icache_function_type,
					"INLINE_ICACHE", "\n");
      print_function_name (file,
			   function->name,
			   NULL, NULL, NULL, function_name_prefix_icache);
      lf_printf (file, "\n(");
      print_icache_function_formal (file, 0);
      lf_printf (file, ")\n");
      lf_printf (file, "{\n");
      lf_indent (file, +2);
      lf_printf (file, "/* semantic routine */\n");
      if (options.gen.semantic_icache)
	{
	  lf_print__line_ref (file, function->code->line);
	  table_print_code (file, function->code);
	  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->name,
			       NULL,
			       NULL, NULL, function_name_prefix_semantics);
	  lf_printf (file, ";\n");
	}

      lf_print__internal_ref (file);
      lf_indent (file, -2);
      lf_printf (file, "}\n");
    }
}
Beispiel #2
0
static void
support_c_function (lf *file, function_entry * function, void *data)
{
  ASSERT (function->type != NULL);
  print_support_function_name (file, function, 1 /*!is_definition */ );
  lf_printf (file, "{\n");
  lf_indent (file, +2);
  if (function->code == NULL)
    error (function->line, "Function without body (or null statement)");
  lf_print__line_ref (file, function->code->line);
  table_print_code (file, function->code);
  if (function->is_internal)
    {
      lf_printf (file,
		 "sim_engine_abort (SD, CPU, cia, \"Internal function must longjump\\n\");\n");
      lf_printf (file, "return cia;\n");
    }
  lf_indent (file, -2);
  lf_printf (file, "}\n");
  lf_print__internal_ref (file);
  lf_printf (file, "\n");
}
Beispiel #3
0
void
print_semantic_body (lf *file,
		     insn_entry * instruction,
		     opcode_bits *expanded_bits, insn_opcodes *opcodes)
{
  /* validate the instruction, if a cache this has already been done */
  if (!options.gen.icache)
    {
      print_idecode_validate (file, instruction, opcodes);
    }

  print_itrace (file, instruction, 0 /*put_value_in_cache */ );

  /* generate the instruction profile call - this is delayed until
     after the instruction has been verified.  The count macro
     generated is prefixed by ITABLE_PREFIX */
  {
    lf_printf (file, "\n");
    lf_indent_suppress (file);
    lf_printf (file, "#if defined (%sPROFILE_COUNT_INSN)\n",
	       options.module.itable.prefix.u);
    lf_printf (file, "%sPROFILE_COUNT_INSN (CPU, CIA, MY_INDEX);\n",
	       options.module.itable.prefix.u);
    lf_indent_suppress (file);
    lf_printf (file, "#endif\n");
  }

  /* generate the model call - this is delayed until after the
     instruction has been verified */
  {
    lf_printf (file, "\n");
    lf_indent_suppress (file);
    lf_printf (file, "#if defined (WITH_MON)\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->name,
			 instruction->format_name,
			 NULL, NULL, function_name_prefix_itable);
    lf_printf (file, ", cpu, cia);\n");
    lf_indent_suppress (file);
    lf_printf (file, "#endif\n");
    lf_printf (file, "\n");
  }

  /* determine the new instruction address */
  {
    lf_printf (file, "/* keep the next instruction address handy */\n");
    if (options.gen.nia == nia_is_invalid)
      {
	lf_printf (file, "nia = %sINVALID_INSTRUCTION_ADDRESS;\n",
		   options.module.global.prefix.u);
      }
    else
      {
	int nr_immeds = instruction->nr_words - 1;
	if (options.gen.delayed_branch)
	  {
	    if (nr_immeds > 0)
	      {
		lf_printf (file, "cia.dp += %d * %d; %s\n",
			   options.insn_bit_size / 8, nr_immeds,
			   "/* skip dp immeds */");
	      }
	    lf_printf (file, "nia.ip = cia.dp; %s\n",
		       "/* instruction pointer */");
	    lf_printf (file, "nia.dp = cia.dp + %d; %s\n",
		       options.insn_bit_size / 8,
		       "/* delayed-slot pointer */");
	  }
	else
	  {
	    if (nr_immeds > 0)
	      {
		lf_printf (file, "nia = cia + %d * (%d + 1); %s\n",
			   options.insn_bit_size / 8, nr_immeds,
			   "/* skip immeds as well */");

	      }
	    else
	      {
		lf_printf (file, "nia = cia + %d;\n",
			   options.insn_bit_size / 8);
	      }
	  }
      }
  }

  /* if conditional, generate code to verify that the instruction
     should be issued */
  if (filter_is_member (instruction->options, "c")
      || options.gen.conditional_issue)
    {
      lf_printf (file, "\n");
      lf_printf (file, "/* execute only if conditional passes */\n");
      lf_printf (file, "if (IS_CONDITION_OK)\n");
      lf_printf (file, "  {\n");
      lf_indent (file, +4);
      /* FIXME - need to log a conditional failure */
    }

  /* Architecture expects a REG to be zero.  Instead of having to
     check every read to see if it is refering to that REG just zap it
     at the start of every instruction */
  if (options.gen.zero_reg)
    {
      lf_printf (file, "\n");
      lf_printf (file, "/* Architecture expects REG to be zero */\n");
      lf_printf (file, "GPR_CLEAR(%d);\n", options.gen.zero_reg_nr);
    }

  /* generate the code (or at least something */
  lf_printf (file, "\n");
  lf_printf (file, "/* semantics: */\n");
  if (instruction->code != NULL)
    {
      /* true code */
      lf_printf (file, "{\n");
      lf_indent (file, +2);
      lf_print__line_ref (file, instruction->code->line);
      table_print_code (file, instruction->code);
      lf_indent (file, -2);
      lf_printf (file, "}\n");
      lf_print__internal_ref (file);
    }
  else if (filter_is_member (instruction->options, "nop"))
    {
      lf_print__internal_ref (file);
    }
  else
    {
      const char *prefix = "sim_engine_abort (";
      int indent = strlen (prefix);
      /* abort so it is implemented now */
      lf_print__line_ref (file, instruction->line);
      lf_printf (file, "%sSD, CPU, cia, \\\n", prefix);
      lf_indent (file, +indent);
      lf_printf (file, "\"%s:%d:0x%%08lx:%%s unimplemented\\n\", \\\n",
		 filter_filename (instruction->line->file_name),
		 instruction->line->line_nr);
      lf_printf (file, "(long) CIA, \\\n");
      lf_printf (file, "%sitable[MY_INDEX].name);\n",
		 options.module.itable.prefix.l);
      lf_indent (file, -indent);
      lf_print__internal_ref (file);
    }

  /* Close off the conditional execution */
  if (filter_is_member (instruction->options, "c")
      || options.gen.conditional_issue)
    {
      lf_indent (file, -4);
      lf_printf (file, "  }\n");
    }
}