00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029
00030
00031 enum s390_opcode_mode_val
00032 {
00033 S390_OPCODE_ESA = 0,
00034 S390_OPCODE_ZARCH
00035 };
00036
00037 enum s390_opcode_cpu_val
00038 {
00039 S390_OPCODE_G5 = 0,
00040 S390_OPCODE_G6,
00041 S390_OPCODE_Z900,
00042 S390_OPCODE_Z990
00043 };
00044
00045 struct op_struct
00046 {
00047 char opcode[16];
00048 char mnemonic[16];
00049 char format[16];
00050 int mode_bits;
00051 int min_cpu;
00052
00053 unsigned long long sort_value;
00054 int no_nibbles;
00055 };
00056
00057 struct op_struct *op_array;
00058 int max_ops;
00059 int no_ops;
00060
00061 static void
00062 createTable (void)
00063 {
00064 max_ops = 256;
00065 op_array = malloc (max_ops * sizeof (struct op_struct));
00066 no_ops = 0;
00067 }
00068
00069
00070
00071 static void
00072 insertOpcode (char *opcode, char *mnemonic, char *format,
00073 int min_cpu, int mode_bits)
00074 {
00075 char *str;
00076 unsigned long long sort_value;
00077 int no_nibbles;
00078 int ix, k;
00079
00080 while (no_ops >= max_ops)
00081 {
00082 max_ops = max_ops * 2;
00083 op_array = realloc (op_array, max_ops * sizeof (struct op_struct));
00084 }
00085
00086 sort_value = 0;
00087 str = opcode;
00088 for (ix = 0; ix < 16; ix++)
00089 {
00090 if (*str >= '0' && *str <= '9')
00091 sort_value = (sort_value << 4) + (*str - '0');
00092 else if (*str >= 'a' && *str <= 'f')
00093 sort_value = (sort_value << 4) + (*str - 'a' + 10);
00094 else if (*str >= 'A' && *str <= 'F')
00095 sort_value = (sort_value << 4) + (*str - 'A' + 10);
00096 else if (*str == '?')
00097 sort_value <<= 4;
00098 else
00099 break;
00100 str ++;
00101 }
00102 sort_value <<= 4*(16 - ix);
00103 sort_value += (min_cpu << 8) + mode_bits;
00104 no_nibbles = ix;
00105 for (ix = 0; ix < no_ops; ix++)
00106 if (sort_value > op_array[ix].sort_value)
00107 break;
00108 for (k = no_ops; k > ix; k--)
00109 op_array[k] = op_array[k-1];
00110 strcpy(op_array[ix].opcode, opcode);
00111 strcpy(op_array[ix].mnemonic, mnemonic);
00112 strcpy(op_array[ix].format, format);
00113 op_array[ix].sort_value = sort_value;
00114 op_array[ix].no_nibbles = no_nibbles;
00115 op_array[ix].min_cpu = min_cpu;
00116 op_array[ix].mode_bits = mode_bits;
00117 no_ops++;
00118 }
00119
00120 static char file_header[] =
00121 "/* The opcode table. This file was generated by s390-mkopc.\n\n"
00122 " The format of the opcode table is:\n\n"
00123 " NAME OPCODE MASK OPERANDS\n\n"
00124 " Name is the name of the instruction.\n"
00125 " OPCODE is the instruction opcode.\n"
00126 " MASK is the opcode mask; this is used to tell the disassembler\n"
00127 " which bits in the actual opcode must match OPCODE.\n"
00128 " OPERANDS is the list of operands.\n\n"
00129 " The disassembler reads the table in order and prints the first\n"
00130 " instruction which matches. */\n\n"
00131 "const struct s390_opcode s390_opcodes[] =\n {\n";
00132
00133
00134
00135 static void
00136 dumpTable (void)
00137 {
00138 char *str;
00139 int ix;
00140
00141
00142 printf (file_header);
00143
00144 for (ix = 0; ix < no_ops; ix++)
00145 {
00146 printf (" { \"%s\", ", op_array[ix].mnemonic);
00147 for (str = op_array[ix].opcode; *str != 0; str++)
00148 if (*str == '?')
00149 *str = '0';
00150 printf ("OP%i(0x%sLL), ",
00151 op_array[ix].no_nibbles*4, op_array[ix].opcode);
00152 printf ("MASK_%s, INSTR_%s, ",
00153 op_array[ix].format, op_array[ix].format);
00154 printf ("%i, ", op_array[ix].mode_bits);
00155 printf ("%i}", op_array[ix].min_cpu);
00156 if (ix < no_ops-1)
00157 printf (",\n");
00158 else
00159 printf ("\n");
00160 }
00161 printf ("};\n\n");
00162 printf ("const int s390_num_opcodes =\n");
00163 printf (" sizeof (s390_opcodes) / sizeof (s390_opcodes[0]);\n\n");
00164 }
00165
00166 int
00167 main (void)
00168 {
00169 char currentLine[256];
00170
00171 createTable ();
00172
00173
00174
00175 while (fgets (currentLine, sizeof (currentLine), stdin) != NULL)
00176 {
00177 char opcode[16];
00178 char mnemonic[16];
00179 char format[16];
00180 char description[64];
00181 char cpu_string[16];
00182 char modes_string[16];
00183 int min_cpu;
00184 int mode_bits;
00185 char *str;
00186
00187 if (currentLine[0] == '#')
00188 continue;
00189 memset (opcode, 0, 8);
00190 if (sscanf (currentLine, "%15s %15s %15s \"%[^\"]\" %15s %15s",
00191 opcode, mnemonic, format, description,
00192 cpu_string, modes_string) == 6)
00193 {
00194 if (strcmp (cpu_string, "g5") == 0)
00195 min_cpu = S390_OPCODE_G5;
00196 else if (strcmp (cpu_string, "g6") == 0)
00197 min_cpu = S390_OPCODE_G6;
00198 else if (strcmp (cpu_string, "z900") == 0)
00199 min_cpu = S390_OPCODE_Z900;
00200 else if (strcmp (cpu_string, "z990") == 0)
00201 min_cpu = S390_OPCODE_Z990;
00202 else {
00203 fprintf (stderr, "Couldn't parse cpu string %s\n", cpu_string);
00204 exit (1);
00205 }
00206
00207 str = modes_string;
00208 mode_bits = 0;
00209 do {
00210 if (strncmp (str, "esa", 3) == 0
00211 && (str[3] == 0 || str[3] == ',')) {
00212 mode_bits |= 1 << S390_OPCODE_ESA;
00213 str += 3;
00214 } else if (strncmp (str, "zarch", 5) == 0
00215 && (str[5] == 0 || str[5] == ',')) {
00216 mode_bits |= 1 << S390_OPCODE_ZARCH;
00217 str += 5;
00218 } else {
00219 fprintf (stderr, "Couldn't parse modes string %s\n",
00220 modes_string);
00221 exit (1);
00222 }
00223 if (*str == ',')
00224 str++;
00225 } while (*str != 0);
00226 insertOpcode (opcode, mnemonic, format, min_cpu, mode_bits);
00227 }
00228 else
00229 fprintf (stderr, "Couldn't scan line %s\n", currentLine);
00230 }
00231
00232 dumpTable ();
00233 return 0;
00234 }