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