Example #1
0
static void
print_icache_extraction(lf *file,
			insn *instruction,
			const char *entry_name,
			const char *entry_type,
			const char *entry_expression,
			const char *original_name,
			const char *file_name,
			int line_nr,
			insn_field *cur_field,
			insn_bits *bits,
			icache_decl_type what_to_declare,
			icache_body_type what_to_do,
			const char *reason)
{
  const char *expression;
  ASSERT(entry_name != NULL);

  /* Define a storage area for the cache element */
  if (what_to_declare == undef_variables) {
    /* We've finished with the value - destory it */
    lf_indent_suppress(file);
    lf_printf(file, "#undef %s\n", entry_name);
    return;
  }
  else if (what_to_declare == define_variables) {
    lf_indent_suppress(file);
    lf_printf(file, "#define %s ", entry_name);
  }
  else {
    if (file_name != NULL)
      lf_print__external_reference(file, line_nr, file_name);
    lf_printf(file, "%s const %s UNUSED = ",
	      entry_type == NULL ? "unsigned" : entry_type,
	      entry_name);
  }

  /* define a value for that storage area as determined by what is in
     the cache */
  if (bits != NULL
      && strcmp(entry_name, cur_field->val_string) == 0
      && ((bits->opcode->is_boolean && bits->value == 0)
	  || (!bits->opcode->is_boolean))) {
    /* The simple field has been made constant (as a result of
       expanding instructions or similar).  Remember that for a
       boolean field, value is either 0 (implying the required
       boolean_constant) or nonzero (implying some other value and
       handled later below) - Define the variable accordingly */
    expression = "constant field";
    ASSERT(bits->field == cur_field);
    ASSERT(entry_type == NULL);
    if (bits->opcode->is_boolean)
      lf_printf(file, "%d", bits->opcode->boolean_constant);
    else if (bits->opcode->last < bits->field->last)
      lf_printf(file, "%d",
		bits->value << (bits->field->last - bits->opcode->last));
    else
      lf_printf(file, "%d", bits->value);
  }
  else if (bits != NULL
	   && original_name != NULL
	   && strncmp(entry_name,
		      original_name, strlen(original_name)) == 0
	   && strncmp(entry_name + strlen(original_name),
		      "_is_", strlen("_is_")) == 0
	   && ((bits->opcode->is_boolean
		&& (atol(entry_name + strlen(original_name) + strlen("_is_"))
		    == bits->opcode->boolean_constant))
	       || (!bits->opcode->is_boolean))) {
    expression = "constant compare";
    /* An entry, derived from ORIGINAL_NAME, is testing to see of the
       ORIGINAL_NAME has a specific constant value.  That value
       matching a boolean or constant field */
    if (bits->opcode->is_boolean)
      lf_printf(file, "%d /* %s == %d */",
		bits->value == 0,
		original_name,
		bits->opcode->boolean_constant);
    else if (bits->opcode->last < bits->field->last)
      lf_printf(file, "%d /* %s == %d */",
		(atol(entry_name + strlen(original_name) + strlen("_is_"))
		 == (bits->value << (bits->field->last - bits->opcode->last))),
		original_name,
		(bits->value << (bits->field->last - bits->opcode->last)));
    else
      lf_printf(file, "%d /* %s == %d */",
		(atol(entry_name + strlen(original_name) + strlen("_is_"))
		 == bits->value),
		original_name,
		bits->value);
  }
  else {
    /* put the field in the local variable, possibly also enter it
       into the cache */
    expression = "extraction";
    /* handle the cache */
    if ((what_to_do & get_values_from_icache)
	|| (what_to_do & put_values_in_icache)) {
      lf_printf(file, "cache_entry->crack.%s.%s",
		instruction->file_entry->fields[insn_form],
		entry_name);
      if (what_to_do & put_values_in_icache) /* also put it in the cache? */
	lf_printf(file, " = ");
    }
    if ((what_to_do & put_values_in_icache)
	|| what_to_do == do_not_use_icache) {
      if (cur_field != NULL && strcmp(entry_name, cur_field->val_string) == 0)
	lf_printf(file, "EXTRACTED32(instruction, %d, %d)",
		  i2target(hi_bit_nr, cur_field->first),
		  i2target(hi_bit_nr, cur_field->last));
      else if (entry_expression != NULL)
	lf_printf(file, "%s", entry_expression);
      else
	lf_printf(file, "eval_%s", entry_name);
    }
  }

  if (!((what_to_declare == define_variables)
	|| (what_to_declare == undef_variables)))
    lf_printf(file, ";");
  if (reason != NULL)
    lf_printf(file, " /* %s - %s */", reason, expression);
  lf_printf(file, "\n");
}
Example #2
0
File: gen-icache.c Project: 5kg/gdb
static void
print_icache_extraction (lf *file,
			 const char *format_name,
			 cache_entry_type cache_type,
			 const char *entry_name,
			 const char *entry_type,
			 const char *entry_expression,
			 char *single_insn_field,
			 line_ref *line,
			 insn_field_entry *cur_field,
			 opcode_bits *expanded_bits,
			 icache_decl_type what_to_declare,
			 icache_body_type what_to_do)
{
  const char *expression;
  opcode_bits *bits;
  char *reason;
  ASSERT (format_name != NULL);
  ASSERT (entry_name != NULL);

  /* figure out exactly what should be going on here */
  switch (cache_type)
    {
    case scratch_value:
      if ((what_to_do & put_values_in_icache)
	  || what_to_do == do_not_use_icache)
	{
	  reason = "scratch";
	  what_to_do = do_not_use_icache;
	}
      else
	return;
      break;
    case compute_value:
      if ((what_to_do & get_values_from_icache)
	  || what_to_do == do_not_use_icache)
	{
	  reason = "compute";
	  what_to_do = do_not_use_icache;
	}
      else
	return;
      break;
    case cache_value:
      if ((what_to_declare != undef_variables)
	  || !(what_to_do & put_values_in_icache))
	{
	  reason = "cache";
	  what_to_declare = ((what_to_do & put_values_in_icache)
			     ? declare_variables : what_to_declare);
	}
      else
	return;
      break;
    default:
      abort ();			/* Bad switch.  */
    }

  /* For the type, default to a simple unsigned */
  if (entry_type == NULL || strlen (entry_type) == 0)
    entry_type = "unsigned";

  /* look through the set of expanded sub fields to see if this field
     has been given a constant value */
  for (bits = expanded_bits; bits != NULL; bits = bits->next)
    {
      if (bits->field == cur_field)
	break;
    }

  /* Define a storage area for the cache element */
  switch (what_to_declare)
    {
    case undef_variables:
      /* We've finished with the #define value - destory it */
      lf_indent_suppress (file);
      lf_printf (file, "#undef %s\n", entry_name);
      return;
    case define_variables:
      /* Using direct access for this entry, clear any prior
         definition, then define it */
      lf_indent_suppress (file);
      lf_printf (file, "#undef %s\n", entry_name);
      /* Don't type cast pointer types! */
      lf_indent_suppress (file);
      if (strchr (entry_type, '*') != NULL)
	lf_printf (file, "#define %s (", entry_name);
      else
	lf_printf (file, "#define %s ((%s) ", entry_name, entry_type);
      break;
    case declare_variables:
      /* using variables to define the value */
      if (line != NULL)
	lf_print__line_ref (file, line);
      lf_printf (file, "%s const %s UNUSED = ", entry_type, entry_name);
      break;
    }


  /* define a value for that storage area as determined by what is in
     the cache */
  if (bits != NULL
      && single_insn_field != NULL
      && strcmp (entry_name, single_insn_field) == 0
      && strcmp (entry_name, cur_field->val_string) == 0
      && ((bits->opcode->is_boolean && bits->value == 0)
	  || (!bits->opcode->is_boolean)))
    {
      /* The cache rule is specifying what to do with a simple
         instruction field.

         Because of instruction expansion, the field is either a
         constant value or equal to the specified constant (boolean
         comparison). (The latter indicated by bits->value == 0).

         The case of a field not being equal to the specified boolean
         value is handled later. */
      expression = "constant field";
      ASSERT (bits->field == cur_field);
      if (bits->opcode->is_boolean)
	{
	  ASSERT (bits->value == 0);
	  lf_printf (file, "%d", bits->opcode->boolean_constant);
	}
      else if (bits->opcode->last < bits->field->last)
	{
	  lf_printf (file, "%d",
		     bits->value << (bits->field->last - bits->opcode->last));
	}
      else
	{
	  lf_printf (file, "%d", bits->value);
	}
    }
  else if (bits != NULL
	   && single_insn_field != NULL
	   && strncmp (entry_name,
		       single_insn_field,
		       strlen (single_insn_field)) == 0
	   && strncmp (entry_name + strlen (single_insn_field),
		       "_is_",
		       strlen ("_is_")) == 0
	   && ((bits->opcode->is_boolean
		&& ((unsigned)
		    atol (entry_name + strlen (single_insn_field) +
			  strlen ("_is_")) == bits->opcode->boolean_constant))
	       || (!bits->opcode->is_boolean)))
    {
      /* The cache rule defines an entry for the comparison between a
         single instruction field and a constant.  The value of the
         comparison in someway matches that of the opcode field that
         was made constant through expansion. */
      expression = "constant compare";
      if (bits->opcode->is_boolean)
	{
	  lf_printf (file, "%d /* %s == %d */",
		     bits->value == 0,
		     single_insn_field, bits->opcode->boolean_constant);
	}
      else if (bits->opcode->last < bits->field->last)
	{
	  lf_printf (file, "%d /* %s == %d */",
		     (atol
		      (entry_name + strlen (single_insn_field) +
		       strlen ("_is_")) ==
		      (bits->
		       value << (bits->field->last - bits->opcode->last))),
		     single_insn_field,
		     (bits->
		      value << (bits->field->last - bits->opcode->last)));
	}
      else
	{
	  lf_printf (file, "%d /* %s == %d */",
		     (atol
		      (entry_name + strlen (single_insn_field) +
		       strlen ("_is_")) == bits->value), single_insn_field,
		     bits->value);
	}
    }
  else
    {
      /* put the field in the local variable, possibly also enter it
         into the cache */
      expression = "extraction";
      /* handle the cache */
      if ((what_to_do & get_values_from_icache)
	  || (what_to_do & put_values_in_icache))
	{
	  lf_printf (file, "cache_entry->crack.%s.%s",
		     format_name, entry_name);
	  if (what_to_do & put_values_in_icache)	/* also put it in the cache? */
	    {
	      lf_printf (file, " = ");
	    }
	}
      if ((what_to_do & put_values_in_icache)
	  || what_to_do == do_not_use_icache)
	{
	  if (cur_field != NULL)
	    {
	      if (entry_expression != NULL && strlen (entry_expression) > 0)
		error (line,
		       "Instruction field entry with nonempty expression\n");
	      if (cur_field->first == 0
		  && cur_field->last == options.insn_bit_size - 1)
		lf_printf (file, "(instruction_%d)", cur_field->word_nr);
	      else if (cur_field->last == options.insn_bit_size - 1)
		lf_printf (file, "MASKED%d (instruction_%d, %d, %d)",
			   options.insn_bit_size,
			   cur_field->word_nr,
			   i2target (options.hi_bit_nr, cur_field->first),
			   i2target (options.hi_bit_nr, cur_field->last));
	      else
		lf_printf (file, "EXTRACTED%d (instruction_%d, %d, %d)",
			   options.insn_bit_size,
			   cur_field->word_nr,
			   i2target (options.hi_bit_nr, cur_field->first),
			   i2target (options.hi_bit_nr, cur_field->last));
	    }
	  else
	    {
	      lf_printf (file, "%s", entry_expression);
	    }
	}
    }

  switch (what_to_declare)
    {
    case define_variables:
      lf_printf (file, ")");
      break;
    case undef_variables:
      break;
    case declare_variables:
      lf_printf (file, ";");
      break;
    }

  ASSERT (reason != NULL && expression != NULL);
  lf_printf (file, " /* %s - %s */\n", reason, expression);
}