* gdb.texinfo (Top): Dedicate manual to the memory of Fred Fish.
[deliverable/binutils-gdb.git] / opcodes / s390-mkopc.c
CommitLineData
a85d7ed0 1/* s390-mkopc.c -- Generates opcode table out of s390-opc.txt
9b201bb5 2 Copyright 2000, 2001, 2003, 2007 Free Software Foundation, Inc.
a85d7ed0
NC
3 Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
4
9b201bb5 5 This file is part of the GNU opcodes library.
a85d7ed0 6
9b201bb5 7 This library is free software; you can redistribute it and/or modify
a85d7ed0 8 it under the terms of the GNU General Public License as published by
9b201bb5
NC
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
a85d7ed0 11
9b201bb5
NC
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
a85d7ed0
NC
16
17 You should have received a copy of the GNU General Public License
9b201bb5
NC
18 along with this file; see the file COPYING. If not, write to the
19 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
a85d7ed0
NC
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
af169f23
MS
26/* Taken from opcodes/s390.h */
27enum s390_opcode_mode_val
28 {
29 S390_OPCODE_ESA = 0,
30 S390_OPCODE_ZARCH
31 };
32
33enum s390_opcode_cpu_val
34 {
35 S390_OPCODE_G5 = 0,
36 S390_OPCODE_G6,
bac02689 37 S390_OPCODE_Z900,
ad101263 38 S390_OPCODE_Z990,
b5639b37
MS
39 S390_OPCODE_Z9_109,
40 S390_OPCODE_Z9_EC
af169f23 41 };
a85d7ed0 42
b6849f55
NC
43struct op_struct
44 {
45 char opcode[16];
46 char mnemonic[16];
47 char format[16];
af169f23
MS
48 int mode_bits;
49 int min_cpu;
50
b6849f55
NC
51 unsigned long long sort_value;
52 int no_nibbles;
53 };
a85d7ed0
NC
54
55struct op_struct *op_array;
56int max_ops;
57int no_ops;
58
59static void
b6849f55 60createTable (void)
a85d7ed0 61{
b6849f55
NC
62 max_ops = 256;
63 op_array = malloc (max_ops * sizeof (struct op_struct));
64 no_ops = 0;
a85d7ed0
NC
65}
66
b6849f55
NC
67/* `insertOpcode': insert an op_struct into sorted opcode array. */
68
a85d7ed0 69static void
af169f23
MS
70insertOpcode (char *opcode, char *mnemonic, char *format,
71 int min_cpu, int mode_bits)
a85d7ed0 72{
b6849f55
NC
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));
a85d7ed0 82 }
b6849f55
NC
83
84 sort_value = 0;
85 str = opcode;
86 for (ix = 0; ix < 16; ix++)
87 {
a85d7ed0
NC
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;
b6849f55 98 str ++;
a85d7ed0 99 }
b6849f55 100 sort_value <<= 4*(16 - ix);
af169f23 101 sort_value += (min_cpu << 8) + mode_bits;
b6849f55
NC
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;
af169f23
MS
113 op_array[ix].min_cpu = min_cpu;
114 op_array[ix].mode_bits = mode_bits;
b6849f55 115 no_ops++;
a85d7ed0
NC
116}
117
b6849f55
NC
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. */
a85d7ed0 132
a85d7ed0 133static void
b6849f55 134dumpTable (void)
a85d7ed0 135{
b6849f55
NC
136 char *str;
137 int ix;
a85d7ed0 138
b6849f55
NC
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);
a85d7ed0
NC
145 for (str = op_array[ix].opcode; *str != 0; str++)
146 if (*str == '?')
147 *str = '0';
b6849f55
NC
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);
af169f23
MS
152 printf ("%i, ", op_array[ix].mode_bits);
153 printf ("%i}", op_array[ix].min_cpu);
a85d7ed0 154 if (ix < no_ops-1)
b6849f55 155 printf (",\n");
a85d7ed0 156 else
b6849f55 157 printf ("\n");
a85d7ed0 158 }
b6849f55
NC
159 printf ("};\n\n");
160 printf ("const int s390_num_opcodes =\n");
161 printf (" sizeof (s390_opcodes) / sizeof (s390_opcodes[0]);\n\n");
a85d7ed0
NC
162}
163
a85d7ed0 164int
b6849f55 165main (void)
a85d7ed0 166{
b6849f55
NC
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 {
a85d7ed0
NC
175 char opcode[16];
176 char mnemonic[16];
177 char format[16];
178 char description[64];
af169f23
MS
179 char cpu_string[16];
180 char modes_string[16];
181 int min_cpu;
182 int mode_bits;
183 char *str;
a85d7ed0
NC
184
185 if (currentLine[0] == '#')
186 continue;
b6849f55 187 memset (opcode, 0, 8);
af169f23
MS
188 if (sscanf (currentLine, "%15s %15s %15s \"%[^\"]\" %15s %15s",
189 opcode, mnemonic, format, description,
190 cpu_string, modes_string) == 6)
b6849f55 191 {
af169f23
MS
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;
bac02689
MS
198 else if (strcmp (cpu_string, "z990") == 0)
199 min_cpu = S390_OPCODE_Z990;
ad101263
MS
200 else if (strcmp (cpu_string, "z9-109") == 0)
201 min_cpu = S390_OPCODE_Z9_109;
b5639b37
MS
202 else if (strcmp (cpu_string, "z9-ec") == 0)
203 min_cpu = S390_OPCODE_Z9_EC;
af169f23
MS
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);
b6849f55
NC
229 }
230 else
231 fprintf (stderr, "Couldn't scan line %s\n", currentLine);
a85d7ed0
NC
232 }
233
b6849f55
NC
234 dumpTable ();
235 return 0;
a85d7ed0 236}
This page took 0.410169 seconds and 4 git commands to generate.