/* Simulation code for the CR16 processor.
   Copyright (C) 2008-2021 Free Software Foundation, Inc.
   Contributed by M Ranga Swami Reddy <MR.Swami.Reddy@nsc.com>

   This file is part of GDB, the GNU debugger.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program. If not, see <http://www.gnu.org/licenses/>.  */

/* This must come before any other includes.  */
#include "defs.h"

#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include <string.h>
#include "ansidecl.h"
#include "opcode/cr16.h"

static void write_header (void);
static void write_opcodes (void);
static void write_template (void);

int
main (int argc, char *argv[])
{
  if ((argc > 1) && (strcmp (argv[1],"-h") == 0))
    write_header();
  else if ((argc > 1) && (strcmp (argv[1],"-t") == 0))
    write_template ();
  else
    write_opcodes();
  return 0;
}


static void
write_header (void)
{
  int i = 0; 

  /* Start searching from end of instruction table.  */
  const inst *instruction = &cr16_instruction[NUMOPCODES - 1];

  /* Loop over instruction table until a full match is found.  */
  for ( ; i < NUMOPCODES; i++)
    printf("void OP_%lX_%X (SIM_DESC, SIM_CPU *);\t\t/* %s */\n",
	   cr16_instruction[i].match, (32 - cr16_instruction[i].match_bits),
	   cr16_instruction[i].mnemonic);
}


/* write_template creates a file all required functions, 
   ready to be filled out.  */

static void
write_template (void)
{
  int i = 0,j, k, flags;

  printf ("#include \"defs.h\"\n");
  printf ("#include \"sim-main.h\"\n");
  printf ("#include \"simops.h\"\n\n");

  for ( ; i < NUMOPCODES; i++)
    {
      if (cr16_instruction[i].size != 0)
{
  printf ("/* %s */\nvoid\nOP_%lX_%X (SIM_DESC sd, SIM_CPU *cpu)\n{\n",
	  cr16_instruction[i].mnemonic, cr16_instruction[i].match,
	  (32 - cr16_instruction[i].match_bits));
  
  /* count operands.  */
  j = 0;
  for (k=0;k<5;k++)
    {
      if (cr16_instruction[i].operands[k].op_type == dummy)
                break;
              else
                j++;
    }
  switch (j)
    {
    case 0:
      printf ("printf(\"   %s\\n\");\n",cr16_instruction[i].mnemonic);
      break;
    case 1:
      printf ("printf(\"   %s\\t%%x\\n\",OP[0]);\n",cr16_instruction[i].mnemonic);
      break;
    case 2:
      printf ("printf(\"   %s\\t%%x,%%x\\n\",OP[0],OP[1]);\n",cr16_instruction[i].mnemonic);
      break;
    case 3:
      printf ("printf(\"   %s\\t%%x,%%x,%%x\\n\",OP[0],OP[1],OP[2]);\n",cr16_instruction[i].mnemonic);
      break;
    default:
      fprintf (stderr,"Too many operands: %d\n",j);
    }
  printf ("}\n\n");
}
    }
}


long Opcodes[512];
static int curop=0;

#if 0
static void
check_opcodes( long op)
{
  int i;

  for (i=0;i<curop;i++)
    if (Opcodes[i] == op)
      fprintf(stderr,"DUPLICATE OPCODES: %lx\n", op);
}
#endif

static void
write_opcodes (void)
{
  int i = 0, j = 0, k;
  
  /* write out opcode table.  */
  printf ("#include \"defs.h\"\n");
  printf ("#include \"sim-main.h\"\n");
  printf ("#include \"simops.h\"\n\n");
  printf ("struct simops Simops[] = {\n");
  
  for (i = NUMOPCODES-1; i >= 0; --i)
    {
      if (cr16_instruction[i].size != 0)
{
           printf ("  { \"%s\", %u, %d, %ld, %u, \"OP_%lX_%X\", OP_%lX_%X, ", 
                    cr16_instruction[i].mnemonic, cr16_instruction[i].size, 
                    cr16_instruction[i].match_bits, cr16_instruction[i].match,
                     cr16_instruction[i].flags, ((BIN(cr16_instruction[i].match, cr16_instruction[i].match_bits))>>(cr16_instruction[i].match_bits)),
             (32 - cr16_instruction[i].match_bits),
                     ((BIN(cr16_instruction[i].match, cr16_instruction[i].match_bits))>>(cr16_instruction[i].match_bits)), (32 - cr16_instruction[i].match_bits));
      
  j = 0;
  for (k=0;k<5;k++)
    {
      if (cr16_instruction[i].operands[k].op_type == dummy)
                break;
              else
                j++;
    }
  printf ("%d, ",j);
  
  j = 0;
  for (k=0;k<4;k++)
    {
      int optype = cr16_instruction[i].operands[k].op_type;
      int shift = cr16_instruction[i].operands[k].shift;
      if (j == 0)
        printf ("{");
      else
        printf (", ");
      printf ("{");
      printf ("%d,%d",optype, shift);
      printf ("}");
      j = 1;
   }
 if (j)
  printf ("}");
 printf ("},\n");
        }
    }
  printf (" { \"NULL\",1,8,0,0,\"OP_0_20\",OP_0_20,0,{{0,0},{0,0},{0,0},{0,0}}},\n};\n");
}
