1 /* s390-mkopc.c -- Generates opcode table out of s390-opc.txt 2 Copyright 2000, 2001 Free Software Foundation, Inc. 3 Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). 4 5 This file is part of GDB, GAS, and the GNU binutils. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 02111-1307, USA. */ 21 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 26 /* Taken from opcodes/s390.h */ 27 enum s390_opcode_mode_val 28 { 29 S390_OPCODE_ESA = 0, 30 S390_OPCODE_ZARCH 31 }; 32 33 enum s390_opcode_cpu_val 34 { 35 S390_OPCODE_G5 = 0, 36 S390_OPCODE_G6, 37 S390_OPCODE_Z900, 38 S390_OPCODE_Z990 39 }; 40 41 struct op_struct 42 { 43 char opcode[16]; 44 char mnemonic[16]; 45 char format[16]; 46 int mode_bits; 47 int min_cpu; 48 49 unsigned long long sort_value; 50 int no_nibbles; 51 }; 52 53 struct op_struct *op_array; 54 int max_ops; 55 int no_ops; 56 57 static void 58 createTable (void) 59 { 60 max_ops = 256; 61 op_array = malloc (max_ops * sizeof (struct op_struct)); 62 no_ops = 0; 63 } 64 65 /* `insertOpcode': insert an op_struct into sorted opcode array. */ 66 67 static void 68 insertOpcode (char *opcode, char *mnemonic, char *format, 69 int min_cpu, int mode_bits) 70 { 71 char *str; 72 unsigned long long sort_value; 73 int no_nibbles; 74 int ix, k; 75 76 while (no_ops >= max_ops) 77 { 78 max_ops = max_ops * 2; 79 op_array = realloc (op_array, max_ops * sizeof (struct op_struct)); 80 } 81 82 sort_value = 0; 83 str = opcode; 84 for (ix = 0; ix < 16; ix++) 85 { 86 if (*str >= '0' && *str <= '9') 87 sort_value = (sort_value << 4) + (*str - '0'); 88 else if (*str >= 'a' && *str <= 'f') 89 sort_value = (sort_value << 4) + (*str - 'a' + 10); 90 else if (*str >= 'A' && *str <= 'F') 91 sort_value = (sort_value << 4) + (*str - 'A' + 10); 92 else if (*str == '?') 93 sort_value <<= 4; 94 else 95 break; 96 str ++; 97 } 98 sort_value <<= 4*(16 - ix); 99 sort_value += (min_cpu << 8) + mode_bits; 100 no_nibbles = ix; 101 for (ix = 0; ix < no_ops; ix++) 102 if (sort_value > op_array[ix].sort_value) 103 break; 104 for (k = no_ops; k > ix; k--) 105 op_array[k] = op_array[k-1]; 106 strcpy(op_array[ix].opcode, opcode); 107 strcpy(op_array[ix].mnemonic, mnemonic); 108 strcpy(op_array[ix].format, format); 109 op_array[ix].sort_value = sort_value; 110 op_array[ix].no_nibbles = no_nibbles; 111 op_array[ix].min_cpu = min_cpu; 112 op_array[ix].mode_bits = mode_bits; 113 no_ops++; 114 } 115 116 static char file_header[] = 117 "/* The opcode table. This file was generated by s390-mkopc.\n\n" 118 " The format of the opcode table is:\n\n" 119 " NAME OPCODE MASK OPERANDS\n\n" 120 " Name is the name of the instruction.\n" 121 " OPCODE is the instruction opcode.\n" 122 " MASK is the opcode mask; this is used to tell the disassembler\n" 123 " which bits in the actual opcode must match OPCODE.\n" 124 " OPERANDS is the list of operands.\n\n" 125 " The disassembler reads the table in order and prints the first\n" 126 " instruction which matches. */\n\n" 127 "const struct s390_opcode s390_opcodes[] =\n {\n"; 128 129 /* `dumpTable': write opcode table. */ 130 131 static void 132 dumpTable (void) 133 { 134 char *str; 135 int ix; 136 137 /* Write hash table entries (slots). */ 138 printf (file_header); 139 140 for (ix = 0; ix < no_ops; ix++) 141 { 142 printf (" { \"%s\", ", op_array[ix].mnemonic); 143 for (str = op_array[ix].opcode; *str != 0; str++) 144 if (*str == '?') 145 *str = '0'; 146 printf ("OP%i(0x%sLL), ", 147 op_array[ix].no_nibbles*4, op_array[ix].opcode); 148 printf ("MASK_%s, INSTR_%s, ", 149 op_array[ix].format, op_array[ix].format); 150 printf ("%i, ", op_array[ix].mode_bits); 151 printf ("%i}", op_array[ix].min_cpu); 152 if (ix < no_ops-1) 153 printf (",\n"); 154 else 155 printf ("\n"); 156 } 157 printf ("};\n\n"); 158 printf ("const int s390_num_opcodes =\n"); 159 printf (" sizeof (s390_opcodes) / sizeof (s390_opcodes[0]);\n\n"); 160 } 161 162 int 163 main (void) 164 { 165 char currentLine[256]; 166 167 createTable (); 168 169 /* Read opcode descriptions from `stdin'. For each mnemonic, 170 make an entry into the opcode table. */ 171 while (fgets (currentLine, sizeof (currentLine), stdin) != NULL) 172 { 173 char opcode[16]; 174 char mnemonic[16]; 175 char format[16]; 176 char description[64]; 177 char cpu_string[16]; 178 char modes_string[16]; 179 int min_cpu; 180 int mode_bits; 181 char *str; 182 183 if (currentLine[0] == '#') 184 continue; 185 memset (opcode, 0, 8); 186 if (sscanf (currentLine, "%15s %15s %15s \"%[^\"]\" %15s %15s", 187 opcode, mnemonic, format, description, 188 cpu_string, modes_string) == 6) 189 { 190 if (strcmp (cpu_string, "g5") == 0) 191 min_cpu = S390_OPCODE_G5; 192 else if (strcmp (cpu_string, "g6") == 0) 193 min_cpu = S390_OPCODE_G6; 194 else if (strcmp (cpu_string, "z900") == 0) 195 min_cpu = S390_OPCODE_Z900; 196 else if (strcmp (cpu_string, "z990") == 0) 197 min_cpu = S390_OPCODE_Z990; 198 else { 199 fprintf (stderr, "Couldn't parse cpu string %s\n", cpu_string); 200 exit (1); 201 } 202 203 str = modes_string; 204 mode_bits = 0; 205 do { 206 if (strncmp (str, "esa", 3) == 0 207 && (str[3] == 0 || str[3] == ',')) { 208 mode_bits |= 1 << S390_OPCODE_ESA; 209 str += 3; 210 } else if (strncmp (str, "zarch", 5) == 0 211 && (str[5] == 0 || str[5] == ',')) { 212 mode_bits |= 1 << S390_OPCODE_ZARCH; 213 str += 5; 214 } else { 215 fprintf (stderr, "Couldn't parse modes string %s\n", 216 modes_string); 217 exit (1); 218 } 219 if (*str == ',') 220 str++; 221 } while (*str != 0); 222 insertOpcode (opcode, mnemonic, format, min_cpu, mode_bits); 223 } 224 else 225 fprintf (stderr, "Couldn't scan line %s\n", currentLine); 226 } 227 228 dumpTable (); 229 return 0; 230 } 231