s390-mkopc.c revision 218822
150477Speter/* s390-mkopc.c -- Generates opcode table out of s390-opc.txt 240843Smsmith Copyright 2000, 2001, 2003 Free Software Foundation, Inc. 3209920Snwhitehorn Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). 496261Sobrien 596261Sobrien This file is part of GDB, GAS, and the GNU binutils. 694290Sdcs 796261Sobrien This program is free software; you can redistribute it and/or modify 896261Sobrien it under the terms of the GNU General Public License as published by 996342Sobrien the Free Software Foundation; either version 2 of the License, or 10125556Sru (at your option) any later version. 1196261Sobrien 12146828Sobrien This program is distributed in the hope that it will be useful, 1364550Speter but WITHOUT ANY WARRANTY; without even the implied warranty of 14148046Sache MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15148046Sache GNU General Public License for more details. 16148046Sache 17209920Snwhitehorn You should have received a copy of the GNU General Public License 18123374Sgrehan along with this program; if not, write to the Free Software 19123374Sgrehan Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 20116000Snyan 02110-1301, USA. */ 21172664Snyan 22116000Snyan#include <stdio.h> 2365677Sdfr#include <stdlib.h> 2496261Sobrien#include <string.h> 2565677Sdfr 2665698Sdfr/* Taken from opcodes/s390.h */ 2796261Sobrienenum s390_opcode_mode_val 2896261Sobrien { 2996261Sobrien S390_OPCODE_ESA = 0, 3056716Sdcs S390_OPCODE_ZARCH 3156716Sdcs }; 3296261Sobrien 33136910Sruenum s390_opcode_cpu_val 3456716Sdcs { 3556716Sdcs S390_OPCODE_G5 = 0, 3640843Smsmith S390_OPCODE_G6, 3740843Smsmith S390_OPCODE_Z900, 3896261Sobrien S390_OPCODE_Z990, 3951786Sdcs S390_OPCODE_Z9_109, 4051786Sdcs S390_OPCODE_Z9_EC 4140843Smsmith }; 4240843Smsmith 4340843Smsmithstruct op_struct 44125556Sru { 45162717Sru char opcode[16]; 46116864Speter char mnemonic[16]; 47116864Speter char format[16]; 48209920Snwhitehorn int mode_bits; 49209920Snwhitehorn int min_cpu; 50209920Snwhitehorn 51209920Snwhitehorn unsigned long long sort_value; 52209920Snwhitehorn int no_nibbles; 53125556Sru }; 5440843Smsmith 5596261Sobrienstruct op_struct *op_array; 5668729Sobrienint max_ops; 5773349Sruint no_ops; 58116864Speter 59125556Srustatic void 60116864SpetercreateTable (void) 61116864Speter{ 62116864Speter max_ops = 256; 63116864Speter op_array = malloc (max_ops * sizeof (struct op_struct)); 64116864Speter no_ops = 0; 65116864Speter} 66116864Speter 67116864Speter/* `insertOpcode': insert an op_struct into sorted opcode array. */ 68116864Speter 69static void 70insertOpcode (char *opcode, char *mnemonic, char *format, 71 int min_cpu, int mode_bits) 72{ 73 char *str; 74 unsigned long long sort_value; 75 int no_nibbles; 76 int ix, k; 77 78 while (no_ops >= max_ops) 79 { 80 max_ops = max_ops * 2; 81 op_array = realloc (op_array, max_ops * sizeof (struct op_struct)); 82 } 83 84 sort_value = 0; 85 str = opcode; 86 for (ix = 0; ix < 16; ix++) 87 { 88 if (*str >= '0' && *str <= '9') 89 sort_value = (sort_value << 4) + (*str - '0'); 90 else if (*str >= 'a' && *str <= 'f') 91 sort_value = (sort_value << 4) + (*str - 'a' + 10); 92 else if (*str >= 'A' && *str <= 'F') 93 sort_value = (sort_value << 4) + (*str - 'A' + 10); 94 else if (*str == '?') 95 sort_value <<= 4; 96 else 97 break; 98 str ++; 99 } 100 sort_value <<= 4*(16 - ix); 101 sort_value += (min_cpu << 8) + mode_bits; 102 no_nibbles = ix; 103 for (ix = 0; ix < no_ops; ix++) 104 if (sort_value > op_array[ix].sort_value) 105 break; 106 for (k = no_ops; k > ix; k--) 107 op_array[k] = op_array[k-1]; 108 strcpy(op_array[ix].opcode, opcode); 109 strcpy(op_array[ix].mnemonic, mnemonic); 110 strcpy(op_array[ix].format, format); 111 op_array[ix].sort_value = sort_value; 112 op_array[ix].no_nibbles = no_nibbles; 113 op_array[ix].min_cpu = min_cpu; 114 op_array[ix].mode_bits = mode_bits; 115 no_ops++; 116} 117 118static char file_header[] = 119 "/* The opcode table. This file was generated by s390-mkopc.\n\n" 120 " The format of the opcode table is:\n\n" 121 " NAME OPCODE MASK OPERANDS\n\n" 122 " Name is the name of the instruction.\n" 123 " OPCODE is the instruction opcode.\n" 124 " MASK is the opcode mask; this is used to tell the disassembler\n" 125 " which bits in the actual opcode must match OPCODE.\n" 126 " OPERANDS is the list of operands.\n\n" 127 " The disassembler reads the table in order and prints the first\n" 128 " instruction which matches. */\n\n" 129 "const struct s390_opcode s390_opcodes[] =\n {\n"; 130 131/* `dumpTable': write opcode table. */ 132 133static void 134dumpTable (void) 135{ 136 char *str; 137 int ix; 138 139 /* Write hash table entries (slots). */ 140 printf (file_header); 141 142 for (ix = 0; ix < no_ops; ix++) 143 { 144 printf (" { \"%s\", ", op_array[ix].mnemonic); 145 for (str = op_array[ix].opcode; *str != 0; str++) 146 if (*str == '?') 147 *str = '0'; 148 printf ("OP%i(0x%sLL), ", 149 op_array[ix].no_nibbles*4, op_array[ix].opcode); 150 printf ("MASK_%s, INSTR_%s, ", 151 op_array[ix].format, op_array[ix].format); 152 printf ("%i, ", op_array[ix].mode_bits); 153 printf ("%i}", op_array[ix].min_cpu); 154 if (ix < no_ops-1) 155 printf (",\n"); 156 else 157 printf ("\n"); 158 } 159 printf ("};\n\n"); 160 printf ("const int s390_num_opcodes =\n"); 161 printf (" sizeof (s390_opcodes) / sizeof (s390_opcodes[0]);\n\n"); 162} 163 164int 165main (void) 166{ 167 char currentLine[256]; 168 169 createTable (); 170 171 /* Read opcode descriptions from `stdin'. For each mnemonic, 172 make an entry into the opcode table. */ 173 while (fgets (currentLine, sizeof (currentLine), stdin) != NULL) 174 { 175 char opcode[16]; 176 char mnemonic[16]; 177 char format[16]; 178 char description[64]; 179 char cpu_string[16]; 180 char modes_string[16]; 181 int min_cpu; 182 int mode_bits; 183 char *str; 184 185 if (currentLine[0] == '#') 186 continue; 187 memset (opcode, 0, 8); 188 if (sscanf (currentLine, "%15s %15s %15s \"%[^\"]\" %15s %15s", 189 opcode, mnemonic, format, description, 190 cpu_string, modes_string) == 6) 191 { 192 if (strcmp (cpu_string, "g5") == 0) 193 min_cpu = S390_OPCODE_G5; 194 else if (strcmp (cpu_string, "g6") == 0) 195 min_cpu = S390_OPCODE_G6; 196 else if (strcmp (cpu_string, "z900") == 0) 197 min_cpu = S390_OPCODE_Z900; 198 else if (strcmp (cpu_string, "z990") == 0) 199 min_cpu = S390_OPCODE_Z990; 200 else if (strcmp (cpu_string, "z9-109") == 0) 201 min_cpu = S390_OPCODE_Z9_109; 202 else if (strcmp (cpu_string, "z9-ec") == 0) 203 min_cpu = S390_OPCODE_Z9_EC; 204 else { 205 fprintf (stderr, "Couldn't parse cpu string %s\n", cpu_string); 206 exit (1); 207 } 208 209 str = modes_string; 210 mode_bits = 0; 211 do { 212 if (strncmp (str, "esa", 3) == 0 213 && (str[3] == 0 || str[3] == ',')) { 214 mode_bits |= 1 << S390_OPCODE_ESA; 215 str += 3; 216 } else if (strncmp (str, "zarch", 5) == 0 217 && (str[5] == 0 || str[5] == ',')) { 218 mode_bits |= 1 << S390_OPCODE_ZARCH; 219 str += 5; 220 } else { 221 fprintf (stderr, "Couldn't parse modes string %s\n", 222 modes_string); 223 exit (1); 224 } 225 if (*str == ',') 226 str++; 227 } while (*str != 0); 228 insertOpcode (opcode, mnemonic, format, min_cpu, mode_bits); 229 } 230 else 231 fprintf (stderr, "Couldn't scan line %s\n", currentLine); 232 } 233 234 dumpTable (); 235 return 0; 236} 237