OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [cpu/] [or32/] [generate.c] - Diff between revs 226 and 230

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 226 Rev 230
Line 139... Line 139...
/* Parses operands. */
/* Parses operands. */
 
 
static int
static int
gen_eval_operands (FILE *fo, int insn_index, int level)
gen_eval_operands (FILE *fo, int insn_index, int level)
{
{
  struct insn_op_struct *opd = op_start[insn_index];
  struct insn_op_struct *opd = or1ksim_op_start[insn_index];
  int i;
  int i;
  int num_ops;
  int num_ops;
  int nbits = 0;
  int nbits = 0;
  int set_param = 0;
  int set_param = 0;
  int dis = 0;
  int dis = 0;
Line 238... Line 238...
      break;
      break;
    opd++;
    opd++;
    i++;
    i++;
  } while (1);
  } while (1);
 
 
  output_function (fo, or32_opcodes[insn_index].function_name, level);
  output_function (fo, or1ksim_or32_opcodes[insn_index].function_name, level);
 
 
  if (set_param)
  if (set_param)
    {
    {
      shift_fprintf (level, fo, "#undef SET_PARAM0\n");
      shift_fprintf (level, fo, "#undef SET_PARAM0\n");
      shift_fprintf (level, fo, "#undef REG_PARAM0\n");
      shift_fprintf (level, fo, "#undef REG_PARAM0\n");
Line 274... Line 274...
 
 
  if (dis_op >= 0)
  if (dis_op >= 0)
    shift_fprintf (level, fo, "cpu_state.insn_ea = %c;\n", 'a' + dis_op);
    shift_fprintf (level, fo, "cpu_state.insn_ea = %c;\n", 'a' + dis_op);
 
 
  shift_fprintf (level, fo, "current->insn_index = %i;   /* \"%s\" */\n", index,
  shift_fprintf (level, fo, "current->insn_index = %i;   /* \"%s\" */\n", index,
                 insn_name (index));
                 or1ksim_insn_name (index));
 
 
  shift_fprintf (level, fo, "analysis(current);\n");
  shift_fprintf (level, fo, "analysis(current);\n");
  shift_fprintf (--level, fo, "}\n");
  shift_fprintf (--level, fo, "}\n");
 
 
  if (write_to_reg)
  if (write_to_reg)
Line 335... Line 335...
}
}
 
 
// List of strings which will be printed on a line after "#include "
// List of strings which will be printed on a line after "#include "
char *include_strings[] = { "<math.h>",
char *include_strings[] = { "<math.h>",
                            "<stdint.h>",
                            "<stdint.h>",
                            "\"execute-fp.h\"",
 
                            ""}; // Last one must be empty
                            ""}; // Last one must be empty
 
 
 
 
/* Generates .c file includes */
/* Generates .c file includes */
static int generate_includes (FILE *fo)
static int generate_includes (FILE *fo)
Line 358... Line 357...
  fprintf (fo, "}\n");
  fprintf (fo, "}\n");
  return 0;
  return 0;
}
}
 
 
/* Decodes all instructions and generates code for that.  This function
/* Decodes all instructions and generates code for that.  This function
   is similar to insn_decode, except it decodes all instructions.
   is similar to or1ksim_insn_decode, except it decodes all instructions.
 
 
   JPB: Added code to generate an illegal instruction exception for invalid
   JPB: Added code to generate an illegal instruction exception for invalid
   instructions. */
   instructions. */
static int generate_body (FILE *fo, unsigned long *a, unsigned long cur_mask, int level)
static int generate_body (FILE *fo, unsigned long *a, unsigned long cur_mask, int level)
{
{
Line 384... Line 383...
        if(prev_inv) {
        if(prev_inv) {
          shift_fprintf (++level, fo, "/* Invalid instruction(s) */\n");
          shift_fprintf (++level, fo, "/* Invalid instruction(s) */\n");
          shift_fprintf (level--, fo, "break;\n");
          shift_fprintf (level--, fo, "break;\n");
        }
        }
        shift_fprintf (level, fo, "case 0x%x:\n", i);
        shift_fprintf (level, fo, "case 0x%x:\n", i);
        generate_body (fo, automata + *a, cur_mask | (mask << shift), ++level);
        generate_body (fo, or1ksim_automata + *a, cur_mask | (mask << shift), ++level);
        shift_fprintf (level--, fo, "break;\n");
        shift_fprintf (level--, fo, "break;\n");
        prev_inv = 0;
        prev_inv = 0;
      }
      }
    }
    }
    if (prev_inv) {
    if (prev_inv) {
Line 400... Line 399...
    shift_fprintf (level, fo, "}\n");
    shift_fprintf (level, fo, "}\n");
  } else {
  } else {
    i = *a & ~LEAF_FLAG;
    i = *a & ~LEAF_FLAG;
 
 
    /* Final check - do we have direct match?
    /* Final check - do we have direct match?
       (based on or32_opcodes this should be the only possibility,
       (based on or1ksim_or32_opcodes this should be the only possibility,
       but in case of invalid/missing instruction we must perform a check)  */
       but in case of invalid/missing instruction we must perform a check)  */
 
 
    if (ti[i].insn_mask != cur_mask) {
    if (or1ksim_ti[i].insn_mask != cur_mask) {
      shift_fprintf (level, fo, "/* Not unique: real mask %08lx and current mask %08lx differ - do final check */\n", ti[i].insn_mask, cur_mask);
      shift_fprintf (level, fo, "/* Not unique: real mask %08lx and current mask %08lx differ - do final check */\n", or1ksim_ti[i].insn_mask, cur_mask);
      shift_fprintf (level++, fo, "if((insn & 0x%x) == 0x%x) {\n",
      shift_fprintf (level++, fo, "if((insn & 0x%x) == 0x%x) {\n",
                     ti[i].insn_mask, ti[i].insn);
                     or1ksim_ti[i].insn_mask, or1ksim_ti[i].insn);
    }
    }
    shift_fprintf (level, fo, "/* Instruction: %s */\n", or32_opcodes[i].name);
    shift_fprintf (level, fo, "/* Instruction: %s */\n", or1ksim_or32_opcodes[i].name);
 
 
    output_call (fo, i, level);
    output_call (fo, i, level);
 
 
    if (ti[i].insn_mask != cur_mask) {
    if (or1ksim_ti[i].insn_mask != cur_mask) {
      shift_fprintf (--level, fo, "} else {\n");
      shift_fprintf (--level, fo, "} else {\n");
      shift_fprintf (++level, fo, "/* Invalid insn */\n");
      shift_fprintf (++level, fo, "/* Invalid insn */\n");
      output_call (fo, -1, level);
      output_call (fo, -1, level);
      shift_fprintf (--level, fo, "}\n");
      shift_fprintf (--level, fo, "}\n");
    }
    }
Line 440... Line 439...
  if (!(fo = fopen (argv[2], "wt+"))) {
  if (!(fo = fopen (argv[2], "wt+"))) {
    fprintf (stderr, "Cannot create '%s'.\n", argv[2]);
    fprintf (stderr, "Cannot create '%s'.\n", argv[2]);
    exit (1);
    exit (1);
  }
  }
 
 
  build_automata (0);
  or1ksim_build_automata (0);
  if (generate_header (fo)) {
  if (generate_header (fo)) {
    fprintf (stderr, "generate_header\n");
    fprintf (stderr, "generate_header\n");
    return 1;
    return 1;
  }
  }
 
 
Line 456... Line 455...
  if (generate_decode_function_header (fo)) {
  if (generate_decode_function_header (fo)) {
    fprintf (stderr, "generate_decode_function_header\n");
    fprintf (stderr, "generate_decode_function_header\n");
    return 1;
    return 1;
  }
  }
 
 
  if (generate_body (fo, automata, 0, 1)) {
  if (generate_body (fo, or1ksim_automata, 0, 1)) {
    fprintf (stderr, "generate_body\n");
    fprintf (stderr, "generate_body\n");
    return 1;
    return 1;
  }
  }
 
 
  if (generate_footer (fo)) {
  if (generate_footer (fo)) {
    fprintf (stderr, "generate_footer\n");
    fprintf (stderr, "generate_footer\n");
    return 1;
    return 1;
  }
  }
 
 
  fclose (fo);
  fclose (fo);
  destruct_automata ();
  or1ksim_destruct_automata ();
  return 0;
  return 0;
}
}
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.