Commit | Line | Data |
---|---|---|
a85d7ed0 | 1 | /* s390-mkopc.c -- Generates opcode table out of s390-opc.txt |
060d22b0 | 2 | Copyright 2000, 2001 Free Software Foundation, Inc. |
a85d7ed0 NC |
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 | /* ARCHBITS_ESA and ARCH_ESAME correspond to the bit numbers defined | |
27 | by s390_opcode_arch_val in include/opcode/s390.h: | |
28 | ARCHBITS_ESAONLY = (1<<S390_OPCODE_ESA) | |
29 | ARCHBITS_ESA = (1<<S390_OPCODE_ESA) + (1<<S390_OPCODE_ESAME) | |
30 | ARCHBITS_ESA = (1<<S390_OPCODE_ESAME). */ | |
31 | #define ARCHBITS_ESAONLY 1 | |
32 | #define ARCHBITS_ESA 3 | |
33 | #define ARCHBITS_ESAME 2 | |
34 | ||
35 | struct op_struct { | |
36 | char opcode[16]; | |
37 | char mnemonic[16]; | |
38 | char format[16]; | |
39 | int archbits; | |
40 | unsigned long long sort_value; | |
41 | int no_nibbles; | |
42 | }; | |
43 | ||
44 | struct op_struct *op_array; | |
45 | int max_ops; | |
46 | int no_ops; | |
47 | ||
48 | static void | |
49 | createTable(void) | |
50 | { | |
51 | max_ops = 256; | |
52 | op_array = malloc(max_ops*sizeof(struct op_struct)); | |
53 | no_ops = 0; | |
54 | } | |
55 | ||
56 | /* | |
57 | * `insertOpcode': insert an op_struct into sorted opcode array | |
58 | */ | |
59 | static void | |
60 | insertOpcode(char *opcode, char *mnemonic, char *format, int archbits) | |
61 | { | |
62 | char *str; | |
63 | unsigned long long sort_value; | |
64 | int no_nibbles; | |
65 | int ix, k; | |
66 | ||
67 | while (no_ops >= max_ops) { | |
68 | max_ops = max_ops*2; | |
69 | op_array = realloc(op_array, max_ops*sizeof(struct op_struct)); | |
70 | } | |
71 | sort_value = 0; | |
72 | str = opcode; | |
73 | for (ix = 0; ix < 16; ix++) { | |
74 | if (*str >= '0' && *str <= '9') | |
75 | sort_value = (sort_value << 4) + (*str - '0'); | |
76 | else if (*str >= 'a' && *str <= 'f') | |
77 | sort_value = (sort_value << 4) + (*str - 'a' + 10); | |
78 | else if (*str >= 'A' && *str <= 'F') | |
79 | sort_value = (sort_value << 4) + (*str - 'A' + 10); | |
80 | else if (*str == '?') | |
81 | sort_value <<= 4; | |
82 | else | |
83 | break; | |
84 | str++; | |
85 | } | |
86 | sort_value <<= 4*(16 - ix); | |
87 | no_nibbles = ix; | |
88 | for (ix = 0; ix < no_ops; ix++) | |
89 | if (sort_value > op_array[ix].sort_value) | |
90 | break; | |
91 | for (k = no_ops; k > ix; k--) | |
92 | op_array[k] = op_array[k-1]; | |
93 | strcpy(op_array[ix].opcode, opcode); | |
94 | strcpy(op_array[ix].mnemonic, mnemonic); | |
95 | strcpy(op_array[ix].format, format); | |
96 | op_array[ix].sort_value = sort_value; | |
97 | op_array[ix].no_nibbles = no_nibbles; | |
98 | op_array[ix].archbits = archbits; | |
99 | no_ops++; | |
100 | } | |
101 | ||
102 | ||
103 | /* | |
104 | * `dumpTable': write opcode table | |
105 | */ | |
106 | static void | |
107 | dumpTable(void) | |
108 | { | |
109 | char *str; | |
110 | int ix; | |
111 | ||
112 | /* Write hash table entries (slots). */ | |
113 | printf("const struct s390_opcode s390_opcodes[] = {\n"); | |
114 | for (ix = 0; ix < no_ops; ix++) { | |
115 | printf(" { \"%s\", ", op_array[ix].mnemonic); | |
116 | for (str = op_array[ix].opcode; *str != 0; str++) | |
117 | if (*str == '?') | |
118 | *str = '0'; | |
119 | printf("OP%i(0x%sLL), ", | |
120 | op_array[ix].no_nibbles*4, op_array[ix].opcode); | |
121 | printf("MASK_%s, INSTR_%s, ", | |
122 | op_array[ix].format, op_array[ix].format); | |
123 | printf("%i}", op_array[ix].archbits); | |
124 | if (ix < no_ops-1) | |
125 | printf(",\n"); | |
126 | else | |
127 | printf("\n"); | |
128 | } | |
129 | printf("};\n\n"); | |
130 | printf("const int s390_num_opcodes =\n"); | |
131 | printf(" sizeof (s390_opcodes) / sizeof (s390_opcodes[0]);\n\n"); | |
132 | } | |
133 | ||
134 | ||
135 | int | |
136 | main(void) | |
137 | { | |
138 | char currentLine[256]; | |
139 | ||
140 | createTable(); | |
141 | /* Read opcode descriptions from `stdin'. For each mnemonic, | |
142 | * make an entry into the opcode table. | |
143 | */ | |
144 | while (fgets(currentLine, sizeof(currentLine), stdin) != NULL) { | |
145 | char opcode[16]; | |
146 | char mnemonic[16]; | |
147 | char format[16]; | |
148 | char description[64]; | |
149 | char archtag[16]; | |
150 | int archbits; | |
151 | ||
152 | if (currentLine[0] == '#') | |
153 | continue; | |
154 | memset(opcode, 0, 8); | |
155 | if (sscanf(currentLine, "%15s %15s %15s \"%[^\"]\" %15s", | |
156 | opcode, mnemonic, format, description, archtag) == 5) { | |
157 | if (strcmp(archtag, "esaonly") == 0) | |
158 | archbits = ARCHBITS_ESAONLY; | |
159 | else if (strcmp(archtag, "esa") == 0) | |
160 | archbits = ARCHBITS_ESA; | |
161 | else if (strcmp(archtag, "esame") == 0) | |
162 | archbits = ARCHBITS_ESAME; | |
163 | else | |
164 | archbits = 0; | |
165 | insertOpcode(opcode, mnemonic, format, archbits); | |
166 | } else | |
167 | fprintf(stderr, "Couldn't scan line %s\n", currentLine); | |
168 | } | |
169 | ||
170 | dumpTable(); | |
171 | return 0; | |
172 | } |