|  | /* Simulation code for the CR16 processor. | 
|  | Copyright (C) 2008-2022 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"); | 
|  | } |