1*7304104dSAndroid Build Coastguard Worker %{
2*7304104dSAndroid Build Coastguard Worker /* Parser for i386 CPU description.
3*7304104dSAndroid Build Coastguard Worker Copyright (C) 2004, 2005, 2007, 2008, 2009 Red Hat, Inc.
4*7304104dSAndroid Build Coastguard Worker Written by Ulrich Drepper <[email protected]>, 2004.
5*7304104dSAndroid Build Coastguard Worker
6*7304104dSAndroid Build Coastguard Worker This file is free software; you can redistribute it and/or modify
7*7304104dSAndroid Build Coastguard Worker it under the terms of either
8*7304104dSAndroid Build Coastguard Worker
9*7304104dSAndroid Build Coastguard Worker * the GNU Lesser General Public License as published by the Free
10*7304104dSAndroid Build Coastguard Worker Software Foundation; either version 3 of the License, or (at
11*7304104dSAndroid Build Coastguard Worker your option) any later version
12*7304104dSAndroid Build Coastguard Worker
13*7304104dSAndroid Build Coastguard Worker or
14*7304104dSAndroid Build Coastguard Worker
15*7304104dSAndroid Build Coastguard Worker * the GNU General Public License as published by the Free
16*7304104dSAndroid Build Coastguard Worker Software Foundation; either version 2 of the License, or (at
17*7304104dSAndroid Build Coastguard Worker your option) any later version
18*7304104dSAndroid Build Coastguard Worker
19*7304104dSAndroid Build Coastguard Worker or both in parallel, as here.
20*7304104dSAndroid Build Coastguard Worker
21*7304104dSAndroid Build Coastguard Worker elfutils is distributed in the hope that it will be useful, but
22*7304104dSAndroid Build Coastguard Worker WITHOUT ANY WARRANTY; without even the implied warranty of
23*7304104dSAndroid Build Coastguard Worker MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24*7304104dSAndroid Build Coastguard Worker General Public License for more details.
25*7304104dSAndroid Build Coastguard Worker
26*7304104dSAndroid Build Coastguard Worker You should have received copies of the GNU General Public License and
27*7304104dSAndroid Build Coastguard Worker the GNU Lesser General Public License along with this program. If
28*7304104dSAndroid Build Coastguard Worker not, see <http://www.gnu.org/licenses/>. */
29*7304104dSAndroid Build Coastguard Worker
30*7304104dSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
31*7304104dSAndroid Build Coastguard Worker # include <config.h>
32*7304104dSAndroid Build Coastguard Worker #endif
33*7304104dSAndroid Build Coastguard Worker
34*7304104dSAndroid Build Coastguard Worker #include <assert.h>
35*7304104dSAndroid Build Coastguard Worker #include <ctype.h>
36*7304104dSAndroid Build Coastguard Worker #include <errno.h>
37*7304104dSAndroid Build Coastguard Worker #include <inttypes.h>
38*7304104dSAndroid Build Coastguard Worker #include <math.h>
39*7304104dSAndroid Build Coastguard Worker #include <obstack.h>
40*7304104dSAndroid Build Coastguard Worker #include <search.h>
41*7304104dSAndroid Build Coastguard Worker #include <stdbool.h>
42*7304104dSAndroid Build Coastguard Worker #include <stdio.h>
43*7304104dSAndroid Build Coastguard Worker #include <stdlib.h>
44*7304104dSAndroid Build Coastguard Worker #include <string.h>
45*7304104dSAndroid Build Coastguard Worker
46*7304104dSAndroid Build Coastguard Worker #include <libeu.h>
47*7304104dSAndroid Build Coastguard Worker #include <system.h>
48*7304104dSAndroid Build Coastguard Worker
49*7304104dSAndroid Build Coastguard Worker #include "i386_mne.h"
50*7304104dSAndroid Build Coastguard Worker
51*7304104dSAndroid Build Coastguard Worker #define obstack_chunk_alloc xmalloc
52*7304104dSAndroid Build Coastguard Worker #define obstack_chunk_free free
53*7304104dSAndroid Build Coastguard Worker
54*7304104dSAndroid Build Coastguard Worker /* The error handler. */
55*7304104dSAndroid Build Coastguard Worker static void yyerror (const char *s);
56*7304104dSAndroid Build Coastguard Worker
57*7304104dSAndroid Build Coastguard Worker extern int yylex (void);
58*7304104dSAndroid Build Coastguard Worker extern int i386_lineno;
59*7304104dSAndroid Build Coastguard Worker extern char *infname;
60*7304104dSAndroid Build Coastguard Worker
61*7304104dSAndroid Build Coastguard Worker
62*7304104dSAndroid Build Coastguard Worker struct known_bitfield
63*7304104dSAndroid Build Coastguard Worker {
64*7304104dSAndroid Build Coastguard Worker char *name;
65*7304104dSAndroid Build Coastguard Worker unsigned long int bits;
66*7304104dSAndroid Build Coastguard Worker int tmp;
67*7304104dSAndroid Build Coastguard Worker };
68*7304104dSAndroid Build Coastguard Worker
69*7304104dSAndroid Build Coastguard Worker
70*7304104dSAndroid Build Coastguard Worker struct bitvalue
71*7304104dSAndroid Build Coastguard Worker {
72*7304104dSAndroid Build Coastguard Worker enum bittype { zeroone, field, failure } type;
73*7304104dSAndroid Build Coastguard Worker union
74*7304104dSAndroid Build Coastguard Worker {
75*7304104dSAndroid Build Coastguard Worker unsigned int value;
76*7304104dSAndroid Build Coastguard Worker struct known_bitfield *field;
77*7304104dSAndroid Build Coastguard Worker };
78*7304104dSAndroid Build Coastguard Worker struct bitvalue *next;
79*7304104dSAndroid Build Coastguard Worker };
80*7304104dSAndroid Build Coastguard Worker
81*7304104dSAndroid Build Coastguard Worker
82*7304104dSAndroid Build Coastguard Worker struct argname
83*7304104dSAndroid Build Coastguard Worker {
84*7304104dSAndroid Build Coastguard Worker enum nametype { string, nfield } type;
85*7304104dSAndroid Build Coastguard Worker union
86*7304104dSAndroid Build Coastguard Worker {
87*7304104dSAndroid Build Coastguard Worker char *str;
88*7304104dSAndroid Build Coastguard Worker struct known_bitfield *field;
89*7304104dSAndroid Build Coastguard Worker };
90*7304104dSAndroid Build Coastguard Worker struct argname *next;
91*7304104dSAndroid Build Coastguard Worker };
92*7304104dSAndroid Build Coastguard Worker
93*7304104dSAndroid Build Coastguard Worker
94*7304104dSAndroid Build Coastguard Worker struct argument
95*7304104dSAndroid Build Coastguard Worker {
96*7304104dSAndroid Build Coastguard Worker struct argname *name;
97*7304104dSAndroid Build Coastguard Worker struct argument *next;
98*7304104dSAndroid Build Coastguard Worker };
99*7304104dSAndroid Build Coastguard Worker
100*7304104dSAndroid Build Coastguard Worker
101*7304104dSAndroid Build Coastguard Worker struct instruction
102*7304104dSAndroid Build Coastguard Worker {
103*7304104dSAndroid Build Coastguard Worker /* The byte encoding. */
104*7304104dSAndroid Build Coastguard Worker struct bitvalue *bytes;
105*7304104dSAndroid Build Coastguard Worker
106*7304104dSAndroid Build Coastguard Worker /* Prefix possible. */
107*7304104dSAndroid Build Coastguard Worker int repe;
108*7304104dSAndroid Build Coastguard Worker int rep;
109*7304104dSAndroid Build Coastguard Worker
110*7304104dSAndroid Build Coastguard Worker /* Mnemonic. */
111*7304104dSAndroid Build Coastguard Worker char *mnemonic;
112*7304104dSAndroid Build Coastguard Worker
113*7304104dSAndroid Build Coastguard Worker /* Suffix. */
114*7304104dSAndroid Build Coastguard Worker enum { suffix_none = 0, suffix_w, suffix_w0, suffix_W, suffix_tttn,
115*7304104dSAndroid Build Coastguard Worker suffix_w1, suffix_W1, suffix_D } suffix;
116*7304104dSAndroid Build Coastguard Worker
117*7304104dSAndroid Build Coastguard Worker /* Flag set if modr/m is used. */
118*7304104dSAndroid Build Coastguard Worker int modrm;
119*7304104dSAndroid Build Coastguard Worker
120*7304104dSAndroid Build Coastguard Worker /* Operands. */
121*7304104dSAndroid Build Coastguard Worker struct operand
122*7304104dSAndroid Build Coastguard Worker {
123*7304104dSAndroid Build Coastguard Worker char *fct;
124*7304104dSAndroid Build Coastguard Worker char *str;
125*7304104dSAndroid Build Coastguard Worker int off1;
126*7304104dSAndroid Build Coastguard Worker int off2;
127*7304104dSAndroid Build Coastguard Worker int off3;
128*7304104dSAndroid Build Coastguard Worker } operands[3];
129*7304104dSAndroid Build Coastguard Worker
130*7304104dSAndroid Build Coastguard Worker struct instruction *next;
131*7304104dSAndroid Build Coastguard Worker };
132*7304104dSAndroid Build Coastguard Worker
133*7304104dSAndroid Build Coastguard Worker
134*7304104dSAndroid Build Coastguard Worker struct synonym
135*7304104dSAndroid Build Coastguard Worker {
136*7304104dSAndroid Build Coastguard Worker char *from;
137*7304104dSAndroid Build Coastguard Worker char *to;
138*7304104dSAndroid Build Coastguard Worker };
139*7304104dSAndroid Build Coastguard Worker
140*7304104dSAndroid Build Coastguard Worker
141*7304104dSAndroid Build Coastguard Worker struct suffix
142*7304104dSAndroid Build Coastguard Worker {
143*7304104dSAndroid Build Coastguard Worker char *name;
144*7304104dSAndroid Build Coastguard Worker int idx;
145*7304104dSAndroid Build Coastguard Worker };
146*7304104dSAndroid Build Coastguard Worker
147*7304104dSAndroid Build Coastguard Worker
148*7304104dSAndroid Build Coastguard Worker struct argstring
149*7304104dSAndroid Build Coastguard Worker {
150*7304104dSAndroid Build Coastguard Worker char *str;
151*7304104dSAndroid Build Coastguard Worker int idx;
152*7304104dSAndroid Build Coastguard Worker int off;
153*7304104dSAndroid Build Coastguard Worker };
154*7304104dSAndroid Build Coastguard Worker
155*7304104dSAndroid Build Coastguard Worker
156*7304104dSAndroid Build Coastguard Worker static struct known_bitfield ax_reg =
157*7304104dSAndroid Build Coastguard Worker {
158*7304104dSAndroid Build Coastguard Worker .name = "ax", .bits = 0, .tmp = 0
159*7304104dSAndroid Build Coastguard Worker };
160*7304104dSAndroid Build Coastguard Worker
161*7304104dSAndroid Build Coastguard Worker static struct known_bitfield dx_reg =
162*7304104dSAndroid Build Coastguard Worker {
163*7304104dSAndroid Build Coastguard Worker .name = "dx", .bits = 0, .tmp = 0
164*7304104dSAndroid Build Coastguard Worker };
165*7304104dSAndroid Build Coastguard Worker
166*7304104dSAndroid Build Coastguard Worker static struct known_bitfield di_reg =
167*7304104dSAndroid Build Coastguard Worker {
168*7304104dSAndroid Build Coastguard Worker .name = "es_di", .bits = 0, .tmp = 0
169*7304104dSAndroid Build Coastguard Worker };
170*7304104dSAndroid Build Coastguard Worker
171*7304104dSAndroid Build Coastguard Worker static struct known_bitfield si_reg =
172*7304104dSAndroid Build Coastguard Worker {
173*7304104dSAndroid Build Coastguard Worker .name = "ds_si", .bits = 0, .tmp = 0
174*7304104dSAndroid Build Coastguard Worker };
175*7304104dSAndroid Build Coastguard Worker
176*7304104dSAndroid Build Coastguard Worker static struct known_bitfield bx_reg =
177*7304104dSAndroid Build Coastguard Worker {
178*7304104dSAndroid Build Coastguard Worker .name = "ds_bx", .bits = 0, .tmp = 0
179*7304104dSAndroid Build Coastguard Worker };
180*7304104dSAndroid Build Coastguard Worker
181*7304104dSAndroid Build Coastguard Worker
182*7304104dSAndroid Build Coastguard Worker static int bitfield_compare (const void *p1, const void *p2);
183*7304104dSAndroid Build Coastguard Worker static void new_bitfield (char *name, unsigned long int num);
184*7304104dSAndroid Build Coastguard Worker static void check_bits (struct bitvalue *value);
185*7304104dSAndroid Build Coastguard Worker static int check_duplicates (struct bitvalue *val);
186*7304104dSAndroid Build Coastguard Worker static int check_argsdef (struct bitvalue *bitval, struct argument *args);
187*7304104dSAndroid Build Coastguard Worker static int check_bitsused (struct bitvalue *bitval,
188*7304104dSAndroid Build Coastguard Worker struct known_bitfield *suffix,
189*7304104dSAndroid Build Coastguard Worker struct argument *args);
190*7304104dSAndroid Build Coastguard Worker static struct argname *combine (struct argname *name);
191*7304104dSAndroid Build Coastguard Worker static void fillin_arg (struct bitvalue *bytes, struct argname *name,
192*7304104dSAndroid Build Coastguard Worker struct instruction *instr, int n);
193*7304104dSAndroid Build Coastguard Worker static void find_numbers (void);
194*7304104dSAndroid Build Coastguard Worker static int compare_syn (const void *p1, const void *p2);
195*7304104dSAndroid Build Coastguard Worker static int compare_suf (const void *p1, const void *p2);
196*7304104dSAndroid Build Coastguard Worker static void instrtable_out (void);
197*7304104dSAndroid Build Coastguard Worker #if 0
198*7304104dSAndroid Build Coastguard Worker static void create_mnemonic_table (void);
199*7304104dSAndroid Build Coastguard Worker #endif
200*7304104dSAndroid Build Coastguard Worker
201*7304104dSAndroid Build Coastguard Worker static void *bitfields;
202*7304104dSAndroid Build Coastguard Worker static struct instruction *instructions;
203*7304104dSAndroid Build Coastguard Worker static size_t ninstructions;
204*7304104dSAndroid Build Coastguard Worker static void *synonyms;
205*7304104dSAndroid Build Coastguard Worker static void *suffixes;
206*7304104dSAndroid Build Coastguard Worker static int nsuffixes;
207*7304104dSAndroid Build Coastguard Worker static void *mnemonics;
208*7304104dSAndroid Build Coastguard Worker size_t nmnemonics;
209*7304104dSAndroid Build Coastguard Worker extern FILE *outfile;
210*7304104dSAndroid Build Coastguard Worker
211*7304104dSAndroid Build Coastguard Worker /* Number of bits used mnemonics. */
212*7304104dSAndroid Build Coastguard Worker #if 0
213*7304104dSAndroid Build Coastguard Worker static size_t best_mnemonic_bits;
214*7304104dSAndroid Build Coastguard Worker #endif
215*7304104dSAndroid Build Coastguard Worker %}
216*7304104dSAndroid Build Coastguard Worker
217*7304104dSAndroid Build Coastguard Worker %union {
218*7304104dSAndroid Build Coastguard Worker unsigned long int num;
219*7304104dSAndroid Build Coastguard Worker char *str;
220*7304104dSAndroid Build Coastguard Worker char ch;
221*7304104dSAndroid Build Coastguard Worker struct known_bitfield *field;
222*7304104dSAndroid Build Coastguard Worker struct bitvalue *bit;
223*7304104dSAndroid Build Coastguard Worker struct argname *name;
224*7304104dSAndroid Build Coastguard Worker struct argument *arg;
225*7304104dSAndroid Build Coastguard Worker }
226*7304104dSAndroid Build Coastguard Worker
227*7304104dSAndroid Build Coastguard Worker %token kMASK
228*7304104dSAndroid Build Coastguard Worker %token kPREFIX
229*7304104dSAndroid Build Coastguard Worker %token kSUFFIX
230*7304104dSAndroid Build Coastguard Worker %token kSYNONYM
231*7304104dSAndroid Build Coastguard Worker %token <str> kID
232*7304104dSAndroid Build Coastguard Worker %token <num> kNUMBER
233*7304104dSAndroid Build Coastguard Worker %token kPERCPERC
234*7304104dSAndroid Build Coastguard Worker %token <str> kBITFIELD
235*7304104dSAndroid Build Coastguard Worker %token <ch> kCHAR
236*7304104dSAndroid Build Coastguard Worker %token kSPACE
237*7304104dSAndroid Build Coastguard Worker
238*7304104dSAndroid Build Coastguard Worker %type <bit> bit byte bytes
239*7304104dSAndroid Build Coastguard Worker %type <field> bitfieldopt
240*7304104dSAndroid Build Coastguard Worker %type <name> argcomp arg
241*7304104dSAndroid Build Coastguard Worker %type <arg> args optargs
242*7304104dSAndroid Build Coastguard Worker
243*7304104dSAndroid Build Coastguard Worker %defines
244*7304104dSAndroid Build Coastguard Worker
245*7304104dSAndroid Build Coastguard Worker %%
246*7304104dSAndroid Build Coastguard Worker
247*7304104dSAndroid Build Coastguard Worker spec: masks kPERCPERC '\n' instrs
248*7304104dSAndroid Build Coastguard Worker {
249*7304104dSAndroid Build Coastguard Worker if (error_message_count != 0)
250*7304104dSAndroid Build Coastguard Worker error (EXIT_FAILURE, 0,
251*7304104dSAndroid Build Coastguard Worker "terminated due to previous error");
252*7304104dSAndroid Build Coastguard Worker
253*7304104dSAndroid Build Coastguard Worker instrtable_out ();
254*7304104dSAndroid Build Coastguard Worker }
255*7304104dSAndroid Build Coastguard Worker ;
256*7304104dSAndroid Build Coastguard Worker
257*7304104dSAndroid Build Coastguard Worker masks: masks '\n' mask
258*7304104dSAndroid Build Coastguard Worker | mask
259*7304104dSAndroid Build Coastguard Worker ;
260*7304104dSAndroid Build Coastguard Worker
261*7304104dSAndroid Build Coastguard Worker mask: kMASK kBITFIELD kNUMBER
262*7304104dSAndroid Build Coastguard Worker { new_bitfield ($2, $3); }
263*7304104dSAndroid Build Coastguard Worker | kPREFIX kBITFIELD
264*7304104dSAndroid Build Coastguard Worker { new_bitfield ($2, -1); }
265*7304104dSAndroid Build Coastguard Worker | kSUFFIX kBITFIELD
266*7304104dSAndroid Build Coastguard Worker { new_bitfield ($2, -2); }
267*7304104dSAndroid Build Coastguard Worker | kSYNONYM kBITFIELD kBITFIELD
268*7304104dSAndroid Build Coastguard Worker {
269*7304104dSAndroid Build Coastguard Worker struct synonym *newp = xmalloc (sizeof (*newp));
270*7304104dSAndroid Build Coastguard Worker newp->from = $2;
271*7304104dSAndroid Build Coastguard Worker newp->to = $3;
272*7304104dSAndroid Build Coastguard Worker if (tfind (newp, &synonyms, compare_syn) != NULL)
273*7304104dSAndroid Build Coastguard Worker error (0, 0,
274*7304104dSAndroid Build Coastguard Worker "%d: duplicate definition for synonym '%s'",
275*7304104dSAndroid Build Coastguard Worker i386_lineno, $2);
276*7304104dSAndroid Build Coastguard Worker else if (tsearch ( newp, &synonyms, compare_syn) == NULL)
277*7304104dSAndroid Build Coastguard Worker error (EXIT_FAILURE, 0, "tsearch");
278*7304104dSAndroid Build Coastguard Worker }
279*7304104dSAndroid Build Coastguard Worker |
280*7304104dSAndroid Build Coastguard Worker ;
281*7304104dSAndroid Build Coastguard Worker
282*7304104dSAndroid Build Coastguard Worker instrs: instrs '\n' instr
283*7304104dSAndroid Build Coastguard Worker | instr
284*7304104dSAndroid Build Coastguard Worker ;
285*7304104dSAndroid Build Coastguard Worker
286*7304104dSAndroid Build Coastguard Worker instr: bytes ':' bitfieldopt kID bitfieldopt optargs
287*7304104dSAndroid Build Coastguard Worker {
288*7304104dSAndroid Build Coastguard Worker if ($3 != NULL && strcmp ($3->name, "RE") != 0
289*7304104dSAndroid Build Coastguard Worker && strcmp ($3->name, "R") != 0)
290*7304104dSAndroid Build Coastguard Worker {
291*7304104dSAndroid Build Coastguard Worker error (0, 0, "%d: only 'R' and 'RE' prefix allowed",
292*7304104dSAndroid Build Coastguard Worker i386_lineno - 1);
293*7304104dSAndroid Build Coastguard Worker }
294*7304104dSAndroid Build Coastguard Worker if (check_duplicates ($1) == 0
295*7304104dSAndroid Build Coastguard Worker && check_argsdef ($1, $6) == 0
296*7304104dSAndroid Build Coastguard Worker && check_bitsused ($1, $5, $6) == 0)
297*7304104dSAndroid Build Coastguard Worker {
298*7304104dSAndroid Build Coastguard Worker struct instruction *newp = xcalloc (sizeof (*newp),
299*7304104dSAndroid Build Coastguard Worker 1);
300*7304104dSAndroid Build Coastguard Worker if ($3 != NULL)
301*7304104dSAndroid Build Coastguard Worker {
302*7304104dSAndroid Build Coastguard Worker if (strcmp ($3->name, "RE") == 0)
303*7304104dSAndroid Build Coastguard Worker newp->repe = 1;
304*7304104dSAndroid Build Coastguard Worker else if (strcmp ($3->name, "R") == 0)
305*7304104dSAndroid Build Coastguard Worker newp->rep = 1;
306*7304104dSAndroid Build Coastguard Worker }
307*7304104dSAndroid Build Coastguard Worker
308*7304104dSAndroid Build Coastguard Worker newp->bytes = $1;
309*7304104dSAndroid Build Coastguard Worker newp->mnemonic = $4;
310*7304104dSAndroid Build Coastguard Worker if (newp->mnemonic != (void *) -1l
311*7304104dSAndroid Build Coastguard Worker && tfind ($4, &mnemonics,
312*7304104dSAndroid Build Coastguard Worker (int (*)(const void *, const void *)) strcmp) == NULL)
313*7304104dSAndroid Build Coastguard Worker {
314*7304104dSAndroid Build Coastguard Worker if (tsearch ($4, &mnemonics,
315*7304104dSAndroid Build Coastguard Worker (int (*)(const void *, const void *)) strcmp) == NULL)
316*7304104dSAndroid Build Coastguard Worker error (EXIT_FAILURE, errno, "tsearch");
317*7304104dSAndroid Build Coastguard Worker ++nmnemonics;
318*7304104dSAndroid Build Coastguard Worker }
319*7304104dSAndroid Build Coastguard Worker
320*7304104dSAndroid Build Coastguard Worker if ($5 != NULL)
321*7304104dSAndroid Build Coastguard Worker {
322*7304104dSAndroid Build Coastguard Worker if (strcmp ($5->name, "w") == 0)
323*7304104dSAndroid Build Coastguard Worker newp->suffix = suffix_w;
324*7304104dSAndroid Build Coastguard Worker else if (strcmp ($5->name, "w0") == 0)
325*7304104dSAndroid Build Coastguard Worker newp->suffix = suffix_w0;
326*7304104dSAndroid Build Coastguard Worker else if (strcmp ($5->name, "tttn") == 0)
327*7304104dSAndroid Build Coastguard Worker newp->suffix = suffix_tttn;
328*7304104dSAndroid Build Coastguard Worker else if (strcmp ($5->name, "w1") == 0)
329*7304104dSAndroid Build Coastguard Worker newp->suffix = suffix_w1;
330*7304104dSAndroid Build Coastguard Worker else if (strcmp ($5->name, "W") == 0)
331*7304104dSAndroid Build Coastguard Worker newp->suffix = suffix_W;
332*7304104dSAndroid Build Coastguard Worker else if (strcmp ($5->name, "W1") == 0)
333*7304104dSAndroid Build Coastguard Worker newp->suffix = suffix_W1;
334*7304104dSAndroid Build Coastguard Worker else if (strcmp ($5->name, "D") == 0)
335*7304104dSAndroid Build Coastguard Worker newp->suffix = suffix_D;
336*7304104dSAndroid Build Coastguard Worker else
337*7304104dSAndroid Build Coastguard Worker error (EXIT_FAILURE, 0,
338*7304104dSAndroid Build Coastguard Worker "%s: %d: unknown suffix '%s'",
339*7304104dSAndroid Build Coastguard Worker infname, i386_lineno - 1, $5->name);
340*7304104dSAndroid Build Coastguard Worker
341*7304104dSAndroid Build Coastguard Worker struct suffix search = { .name = $5->name };
342*7304104dSAndroid Build Coastguard Worker if (tfind (&search, &suffixes, compare_suf)
343*7304104dSAndroid Build Coastguard Worker == NULL)
344*7304104dSAndroid Build Coastguard Worker {
345*7304104dSAndroid Build Coastguard Worker struct suffix *ns = xmalloc (sizeof (*ns));
346*7304104dSAndroid Build Coastguard Worker ns->name = $5->name;
347*7304104dSAndroid Build Coastguard Worker ns->idx = ++nsuffixes;
348*7304104dSAndroid Build Coastguard Worker if (tsearch (ns, &suffixes, compare_suf)
349*7304104dSAndroid Build Coastguard Worker == NULL)
350*7304104dSAndroid Build Coastguard Worker error (EXIT_FAILURE, errno, "tsearch");
351*7304104dSAndroid Build Coastguard Worker }
352*7304104dSAndroid Build Coastguard Worker }
353*7304104dSAndroid Build Coastguard Worker
354*7304104dSAndroid Build Coastguard Worker struct argument *args = $6;
355*7304104dSAndroid Build Coastguard Worker int n = 0;
356*7304104dSAndroid Build Coastguard Worker while (args != NULL)
357*7304104dSAndroid Build Coastguard Worker {
358*7304104dSAndroid Build Coastguard Worker fillin_arg ($1, args->name, newp, n);
359*7304104dSAndroid Build Coastguard Worker
360*7304104dSAndroid Build Coastguard Worker args = args->next;
361*7304104dSAndroid Build Coastguard Worker ++n;
362*7304104dSAndroid Build Coastguard Worker }
363*7304104dSAndroid Build Coastguard Worker
364*7304104dSAndroid Build Coastguard Worker newp->next = instructions;
365*7304104dSAndroid Build Coastguard Worker instructions = newp;
366*7304104dSAndroid Build Coastguard Worker ++ninstructions;
367*7304104dSAndroid Build Coastguard Worker }
368*7304104dSAndroid Build Coastguard Worker }
369*7304104dSAndroid Build Coastguard Worker |
370*7304104dSAndroid Build Coastguard Worker ;
371*7304104dSAndroid Build Coastguard Worker
372*7304104dSAndroid Build Coastguard Worker bitfieldopt: kBITFIELD
373*7304104dSAndroid Build Coastguard Worker {
374*7304104dSAndroid Build Coastguard Worker struct known_bitfield search;
375*7304104dSAndroid Build Coastguard Worker search.name = $1;
376*7304104dSAndroid Build Coastguard Worker struct known_bitfield **res;
377*7304104dSAndroid Build Coastguard Worker res = tfind (&search, &bitfields, bitfield_compare);
378*7304104dSAndroid Build Coastguard Worker if (res == NULL)
379*7304104dSAndroid Build Coastguard Worker {
380*7304104dSAndroid Build Coastguard Worker error (0, 0, "%d: unknown bitfield '%s'",
381*7304104dSAndroid Build Coastguard Worker i386_lineno, search.name);
382*7304104dSAndroid Build Coastguard Worker $$ = NULL;
383*7304104dSAndroid Build Coastguard Worker }
384*7304104dSAndroid Build Coastguard Worker else
385*7304104dSAndroid Build Coastguard Worker $$ = *res;
386*7304104dSAndroid Build Coastguard Worker }
387*7304104dSAndroid Build Coastguard Worker |
388*7304104dSAndroid Build Coastguard Worker { $$ = NULL; }
389*7304104dSAndroid Build Coastguard Worker ;
390*7304104dSAndroid Build Coastguard Worker
391*7304104dSAndroid Build Coastguard Worker bytes: bytes ',' byte
392*7304104dSAndroid Build Coastguard Worker {
393*7304104dSAndroid Build Coastguard Worker check_bits ($3);
394*7304104dSAndroid Build Coastguard Worker
395*7304104dSAndroid Build Coastguard Worker struct bitvalue *runp = $1;
396*7304104dSAndroid Build Coastguard Worker while (runp->next != NULL)
397*7304104dSAndroid Build Coastguard Worker runp = runp->next;
398*7304104dSAndroid Build Coastguard Worker runp->next = $3;
399*7304104dSAndroid Build Coastguard Worker $$ = $1;
400*7304104dSAndroid Build Coastguard Worker }
401*7304104dSAndroid Build Coastguard Worker | byte
402*7304104dSAndroid Build Coastguard Worker {
403*7304104dSAndroid Build Coastguard Worker check_bits ($1);
404*7304104dSAndroid Build Coastguard Worker $$ = $1;
405*7304104dSAndroid Build Coastguard Worker }
406*7304104dSAndroid Build Coastguard Worker ;
407*7304104dSAndroid Build Coastguard Worker
408*7304104dSAndroid Build Coastguard Worker byte: byte bit
409*7304104dSAndroid Build Coastguard Worker {
410*7304104dSAndroid Build Coastguard Worker struct bitvalue *runp = $1;
411*7304104dSAndroid Build Coastguard Worker while (runp->next != NULL)
412*7304104dSAndroid Build Coastguard Worker runp = runp->next;
413*7304104dSAndroid Build Coastguard Worker runp->next = $2;
414*7304104dSAndroid Build Coastguard Worker $$ = $1;
415*7304104dSAndroid Build Coastguard Worker }
416*7304104dSAndroid Build Coastguard Worker | bit
417*7304104dSAndroid Build Coastguard Worker { $$ = $1; }
418*7304104dSAndroid Build Coastguard Worker ;
419*7304104dSAndroid Build Coastguard Worker
420*7304104dSAndroid Build Coastguard Worker bit: '0'
421*7304104dSAndroid Build Coastguard Worker {
422*7304104dSAndroid Build Coastguard Worker $$ = xmalloc (sizeof (struct bitvalue));
423*7304104dSAndroid Build Coastguard Worker $$->type = zeroone;
424*7304104dSAndroid Build Coastguard Worker $$->value = 0;
425*7304104dSAndroid Build Coastguard Worker $$->next = NULL;
426*7304104dSAndroid Build Coastguard Worker }
427*7304104dSAndroid Build Coastguard Worker | '1'
428*7304104dSAndroid Build Coastguard Worker {
429*7304104dSAndroid Build Coastguard Worker $$ = xmalloc (sizeof (struct bitvalue));
430*7304104dSAndroid Build Coastguard Worker $$->type = zeroone;
431*7304104dSAndroid Build Coastguard Worker $$->value = 1;
432*7304104dSAndroid Build Coastguard Worker $$->next = NULL;
433*7304104dSAndroid Build Coastguard Worker }
434*7304104dSAndroid Build Coastguard Worker | kBITFIELD
435*7304104dSAndroid Build Coastguard Worker {
436*7304104dSAndroid Build Coastguard Worker $$ = xmalloc (sizeof (struct bitvalue));
437*7304104dSAndroid Build Coastguard Worker struct known_bitfield search;
438*7304104dSAndroid Build Coastguard Worker search.name = $1;
439*7304104dSAndroid Build Coastguard Worker struct known_bitfield **res;
440*7304104dSAndroid Build Coastguard Worker res = tfind (&search, &bitfields, bitfield_compare);
441*7304104dSAndroid Build Coastguard Worker if (res == NULL)
442*7304104dSAndroid Build Coastguard Worker {
443*7304104dSAndroid Build Coastguard Worker error (0, 0, "%d: unknown bitfield '%s'",
444*7304104dSAndroid Build Coastguard Worker i386_lineno, search.name);
445*7304104dSAndroid Build Coastguard Worker $$->type = failure;
446*7304104dSAndroid Build Coastguard Worker }
447*7304104dSAndroid Build Coastguard Worker else
448*7304104dSAndroid Build Coastguard Worker {
449*7304104dSAndroid Build Coastguard Worker $$->type = field;
450*7304104dSAndroid Build Coastguard Worker $$->field = *res;
451*7304104dSAndroid Build Coastguard Worker }
452*7304104dSAndroid Build Coastguard Worker $$->next = NULL;
453*7304104dSAndroid Build Coastguard Worker }
454*7304104dSAndroid Build Coastguard Worker ;
455*7304104dSAndroid Build Coastguard Worker
456*7304104dSAndroid Build Coastguard Worker optargs: kSPACE args
457*7304104dSAndroid Build Coastguard Worker { $$ = $2; }
458*7304104dSAndroid Build Coastguard Worker |
459*7304104dSAndroid Build Coastguard Worker { $$ = NULL; }
460*7304104dSAndroid Build Coastguard Worker ;
461*7304104dSAndroid Build Coastguard Worker
462*7304104dSAndroid Build Coastguard Worker args: args ',' arg
463*7304104dSAndroid Build Coastguard Worker {
464*7304104dSAndroid Build Coastguard Worker struct argument *runp = $1;
465*7304104dSAndroid Build Coastguard Worker while (runp->next != NULL)
466*7304104dSAndroid Build Coastguard Worker runp = runp->next;
467*7304104dSAndroid Build Coastguard Worker runp->next = xmalloc (sizeof (struct argument));
468*7304104dSAndroid Build Coastguard Worker runp->next->name = combine ($3);
469*7304104dSAndroid Build Coastguard Worker runp->next->next = NULL;
470*7304104dSAndroid Build Coastguard Worker $$ = $1;
471*7304104dSAndroid Build Coastguard Worker }
472*7304104dSAndroid Build Coastguard Worker | arg
473*7304104dSAndroid Build Coastguard Worker {
474*7304104dSAndroid Build Coastguard Worker $$ = xmalloc (sizeof (struct argument));
475*7304104dSAndroid Build Coastguard Worker $$->name = combine ($1);
476*7304104dSAndroid Build Coastguard Worker $$->next = NULL;
477*7304104dSAndroid Build Coastguard Worker }
478*7304104dSAndroid Build Coastguard Worker ;
479*7304104dSAndroid Build Coastguard Worker
480*7304104dSAndroid Build Coastguard Worker arg: arg argcomp
481*7304104dSAndroid Build Coastguard Worker {
482*7304104dSAndroid Build Coastguard Worker struct argname *runp = $1;
483*7304104dSAndroid Build Coastguard Worker while (runp->next != NULL)
484*7304104dSAndroid Build Coastguard Worker runp = runp->next;
485*7304104dSAndroid Build Coastguard Worker runp->next = $2;
486*7304104dSAndroid Build Coastguard Worker $$ = $1;
487*7304104dSAndroid Build Coastguard Worker }
488*7304104dSAndroid Build Coastguard Worker | argcomp
489*7304104dSAndroid Build Coastguard Worker { $$ = $1; }
490*7304104dSAndroid Build Coastguard Worker ;
491*7304104dSAndroid Build Coastguard Worker argcomp: kBITFIELD
492*7304104dSAndroid Build Coastguard Worker {
493*7304104dSAndroid Build Coastguard Worker $$ = xmalloc (sizeof (struct argname));
494*7304104dSAndroid Build Coastguard Worker $$->type = nfield;
495*7304104dSAndroid Build Coastguard Worker $$->next = NULL;
496*7304104dSAndroid Build Coastguard Worker
497*7304104dSAndroid Build Coastguard Worker struct known_bitfield search;
498*7304104dSAndroid Build Coastguard Worker search.name = $1;
499*7304104dSAndroid Build Coastguard Worker struct known_bitfield **res;
500*7304104dSAndroid Build Coastguard Worker res = tfind (&search, &bitfields, bitfield_compare);
501*7304104dSAndroid Build Coastguard Worker if (res == NULL)
502*7304104dSAndroid Build Coastguard Worker {
503*7304104dSAndroid Build Coastguard Worker if (strcmp ($1, "ax") == 0)
504*7304104dSAndroid Build Coastguard Worker $$->field = &ax_reg;
505*7304104dSAndroid Build Coastguard Worker else if (strcmp ($1, "dx") == 0)
506*7304104dSAndroid Build Coastguard Worker $$->field = &dx_reg;
507*7304104dSAndroid Build Coastguard Worker else if (strcmp ($1, "es_di") == 0)
508*7304104dSAndroid Build Coastguard Worker $$->field = &di_reg;
509*7304104dSAndroid Build Coastguard Worker else if (strcmp ($1, "ds_si") == 0)
510*7304104dSAndroid Build Coastguard Worker $$->field = &si_reg;
511*7304104dSAndroid Build Coastguard Worker else if (strcmp ($1, "ds_bx") == 0)
512*7304104dSAndroid Build Coastguard Worker $$->field = &bx_reg;
513*7304104dSAndroid Build Coastguard Worker else
514*7304104dSAndroid Build Coastguard Worker {
515*7304104dSAndroid Build Coastguard Worker error (0, 0, "%d: unknown bitfield '%s'",
516*7304104dSAndroid Build Coastguard Worker i386_lineno, search.name);
517*7304104dSAndroid Build Coastguard Worker $$->field = NULL;
518*7304104dSAndroid Build Coastguard Worker }
519*7304104dSAndroid Build Coastguard Worker }
520*7304104dSAndroid Build Coastguard Worker else
521*7304104dSAndroid Build Coastguard Worker $$->field = *res;
522*7304104dSAndroid Build Coastguard Worker }
523*7304104dSAndroid Build Coastguard Worker | kCHAR
524*7304104dSAndroid Build Coastguard Worker {
525*7304104dSAndroid Build Coastguard Worker $$ = xmalloc (sizeof (struct argname));
526*7304104dSAndroid Build Coastguard Worker $$->type = string;
527*7304104dSAndroid Build Coastguard Worker $$->next = NULL;
528*7304104dSAndroid Build Coastguard Worker $$->str = xmalloc (2);
529*7304104dSAndroid Build Coastguard Worker $$->str[0] = $1;
530*7304104dSAndroid Build Coastguard Worker $$->str[1] = '\0';
531*7304104dSAndroid Build Coastguard Worker }
532*7304104dSAndroid Build Coastguard Worker | kID
533*7304104dSAndroid Build Coastguard Worker {
534*7304104dSAndroid Build Coastguard Worker $$ = xmalloc (sizeof (struct argname));
535*7304104dSAndroid Build Coastguard Worker $$->type = string;
536*7304104dSAndroid Build Coastguard Worker $$->next = NULL;
537*7304104dSAndroid Build Coastguard Worker $$->str = $1;
538*7304104dSAndroid Build Coastguard Worker }
539*7304104dSAndroid Build Coastguard Worker | ':'
540*7304104dSAndroid Build Coastguard Worker {
541*7304104dSAndroid Build Coastguard Worker $$ = xmalloc (sizeof (struct argname));
542*7304104dSAndroid Build Coastguard Worker $$->type = string;
543*7304104dSAndroid Build Coastguard Worker $$->next = NULL;
544*7304104dSAndroid Build Coastguard Worker $$->str = xmalloc (2);
545*7304104dSAndroid Build Coastguard Worker $$->str[0] = ':';
546*7304104dSAndroid Build Coastguard Worker $$->str[1] = '\0';
547*7304104dSAndroid Build Coastguard Worker }
548*7304104dSAndroid Build Coastguard Worker ;
549*7304104dSAndroid Build Coastguard Worker
550*7304104dSAndroid Build Coastguard Worker %%
551*7304104dSAndroid Build Coastguard Worker
552*7304104dSAndroid Build Coastguard Worker static void
553*7304104dSAndroid Build Coastguard Worker yyerror (const char *s)
554*7304104dSAndroid Build Coastguard Worker {
555*7304104dSAndroid Build Coastguard Worker error (0, 0, _("while reading i386 CPU description: %s at line %d"),
556*7304104dSAndroid Build Coastguard Worker _(s), i386_lineno);
557*7304104dSAndroid Build Coastguard Worker }
558*7304104dSAndroid Build Coastguard Worker
559*7304104dSAndroid Build Coastguard Worker
560*7304104dSAndroid Build Coastguard Worker static int
bitfield_compare(const void * p1,const void * p2)561*7304104dSAndroid Build Coastguard Worker bitfield_compare (const void *p1, const void *p2)
562*7304104dSAndroid Build Coastguard Worker {
563*7304104dSAndroid Build Coastguard Worker struct known_bitfield *f1 = (struct known_bitfield *) p1;
564*7304104dSAndroid Build Coastguard Worker struct known_bitfield *f2 = (struct known_bitfield *) p2;
565*7304104dSAndroid Build Coastguard Worker
566*7304104dSAndroid Build Coastguard Worker return strcmp (f1->name, f2->name);
567*7304104dSAndroid Build Coastguard Worker }
568*7304104dSAndroid Build Coastguard Worker
569*7304104dSAndroid Build Coastguard Worker
570*7304104dSAndroid Build Coastguard Worker static void
new_bitfield(char * name,unsigned long int num)571*7304104dSAndroid Build Coastguard Worker new_bitfield (char *name, unsigned long int num)
572*7304104dSAndroid Build Coastguard Worker {
573*7304104dSAndroid Build Coastguard Worker struct known_bitfield *newp = xmalloc (sizeof (struct known_bitfield));
574*7304104dSAndroid Build Coastguard Worker newp->name = name;
575*7304104dSAndroid Build Coastguard Worker newp->bits = num;
576*7304104dSAndroid Build Coastguard Worker newp->tmp = 0;
577*7304104dSAndroid Build Coastguard Worker
578*7304104dSAndroid Build Coastguard Worker if (tfind (newp, &bitfields, bitfield_compare) != NULL)
579*7304104dSAndroid Build Coastguard Worker {
580*7304104dSAndroid Build Coastguard Worker error (0, 0, "%d: duplicated definition of bitfield '%s'",
581*7304104dSAndroid Build Coastguard Worker i386_lineno, name);
582*7304104dSAndroid Build Coastguard Worker free (name);
583*7304104dSAndroid Build Coastguard Worker free (newp);
584*7304104dSAndroid Build Coastguard Worker return;
585*7304104dSAndroid Build Coastguard Worker }
586*7304104dSAndroid Build Coastguard Worker
587*7304104dSAndroid Build Coastguard Worker if (tsearch (newp, &bitfields, bitfield_compare) == NULL)
588*7304104dSAndroid Build Coastguard Worker error (EXIT_FAILURE, errno, "%d: cannot insert new bitfield '%s'",
589*7304104dSAndroid Build Coastguard Worker i386_lineno, name);
590*7304104dSAndroid Build Coastguard Worker }
591*7304104dSAndroid Build Coastguard Worker
592*7304104dSAndroid Build Coastguard Worker
593*7304104dSAndroid Build Coastguard Worker /* Check that the number of bits is a multiple of 8. */
594*7304104dSAndroid Build Coastguard Worker static void
check_bits(struct bitvalue * val)595*7304104dSAndroid Build Coastguard Worker check_bits (struct bitvalue *val)
596*7304104dSAndroid Build Coastguard Worker {
597*7304104dSAndroid Build Coastguard Worker struct bitvalue *runp = val;
598*7304104dSAndroid Build Coastguard Worker unsigned int total = 0;
599*7304104dSAndroid Build Coastguard Worker
600*7304104dSAndroid Build Coastguard Worker while (runp != NULL)
601*7304104dSAndroid Build Coastguard Worker {
602*7304104dSAndroid Build Coastguard Worker if (runp->type == zeroone)
603*7304104dSAndroid Build Coastguard Worker ++total;
604*7304104dSAndroid Build Coastguard Worker else if (runp->field == NULL)
605*7304104dSAndroid Build Coastguard Worker /* No sense doing anything, the field is not known. */
606*7304104dSAndroid Build Coastguard Worker return;
607*7304104dSAndroid Build Coastguard Worker else
608*7304104dSAndroid Build Coastguard Worker total += runp->field->bits;
609*7304104dSAndroid Build Coastguard Worker
610*7304104dSAndroid Build Coastguard Worker runp = runp->next;
611*7304104dSAndroid Build Coastguard Worker }
612*7304104dSAndroid Build Coastguard Worker
613*7304104dSAndroid Build Coastguard Worker if (total % 8 != 0)
614*7304104dSAndroid Build Coastguard Worker {
615*7304104dSAndroid Build Coastguard Worker struct obstack os;
616*7304104dSAndroid Build Coastguard Worker obstack_init (&os);
617*7304104dSAndroid Build Coastguard Worker
618*7304104dSAndroid Build Coastguard Worker while (val != NULL)
619*7304104dSAndroid Build Coastguard Worker {
620*7304104dSAndroid Build Coastguard Worker if (val->type == zeroone)
621*7304104dSAndroid Build Coastguard Worker obstack_printf (&os, "%u", val->value);
622*7304104dSAndroid Build Coastguard Worker else
623*7304104dSAndroid Build Coastguard Worker obstack_printf (&os, "{%s}", val->field->name);
624*7304104dSAndroid Build Coastguard Worker val = val->next;
625*7304104dSAndroid Build Coastguard Worker }
626*7304104dSAndroid Build Coastguard Worker obstack_1grow (&os, '\0');
627*7304104dSAndroid Build Coastguard Worker
628*7304104dSAndroid Build Coastguard Worker error (0, 0, "%d: field '%s' not a multiple of 8 bits in size",
629*7304104dSAndroid Build Coastguard Worker i386_lineno, (char *) obstack_finish (&os));
630*7304104dSAndroid Build Coastguard Worker
631*7304104dSAndroid Build Coastguard Worker obstack_free (&os, NULL);
632*7304104dSAndroid Build Coastguard Worker }
633*7304104dSAndroid Build Coastguard Worker }
634*7304104dSAndroid Build Coastguard Worker
635*7304104dSAndroid Build Coastguard Worker
636*7304104dSAndroid Build Coastguard Worker static int
check_duplicates(struct bitvalue * val)637*7304104dSAndroid Build Coastguard Worker check_duplicates (struct bitvalue *val)
638*7304104dSAndroid Build Coastguard Worker {
639*7304104dSAndroid Build Coastguard Worker static int testcnt;
640*7304104dSAndroid Build Coastguard Worker ++testcnt;
641*7304104dSAndroid Build Coastguard Worker
642*7304104dSAndroid Build Coastguard Worker int result = 0;
643*7304104dSAndroid Build Coastguard Worker while (val != NULL)
644*7304104dSAndroid Build Coastguard Worker {
645*7304104dSAndroid Build Coastguard Worker if (val->type == field && val->field != NULL)
646*7304104dSAndroid Build Coastguard Worker {
647*7304104dSAndroid Build Coastguard Worker if (val->field->tmp == testcnt)
648*7304104dSAndroid Build Coastguard Worker {
649*7304104dSAndroid Build Coastguard Worker error (0, 0, "%d: bitfield '%s' used more than once",
650*7304104dSAndroid Build Coastguard Worker i386_lineno - 1, val->field->name);
651*7304104dSAndroid Build Coastguard Worker result = 1;
652*7304104dSAndroid Build Coastguard Worker }
653*7304104dSAndroid Build Coastguard Worker val->field->tmp = testcnt;
654*7304104dSAndroid Build Coastguard Worker }
655*7304104dSAndroid Build Coastguard Worker
656*7304104dSAndroid Build Coastguard Worker val = val->next;
657*7304104dSAndroid Build Coastguard Worker }
658*7304104dSAndroid Build Coastguard Worker
659*7304104dSAndroid Build Coastguard Worker return result;
660*7304104dSAndroid Build Coastguard Worker }
661*7304104dSAndroid Build Coastguard Worker
662*7304104dSAndroid Build Coastguard Worker
663*7304104dSAndroid Build Coastguard Worker static int
check_argsdef(struct bitvalue * bitval,struct argument * args)664*7304104dSAndroid Build Coastguard Worker check_argsdef (struct bitvalue *bitval, struct argument *args)
665*7304104dSAndroid Build Coastguard Worker {
666*7304104dSAndroid Build Coastguard Worker int result = 0;
667*7304104dSAndroid Build Coastguard Worker
668*7304104dSAndroid Build Coastguard Worker while (args != NULL)
669*7304104dSAndroid Build Coastguard Worker {
670*7304104dSAndroid Build Coastguard Worker for (struct argname *name = args->name; name != NULL; name = name->next)
671*7304104dSAndroid Build Coastguard Worker if (name->type == nfield && name->field != NULL
672*7304104dSAndroid Build Coastguard Worker && name->field != &ax_reg && name->field != &dx_reg
673*7304104dSAndroid Build Coastguard Worker && name->field != &di_reg && name->field != &si_reg
674*7304104dSAndroid Build Coastguard Worker && name->field != &bx_reg)
675*7304104dSAndroid Build Coastguard Worker {
676*7304104dSAndroid Build Coastguard Worker struct bitvalue *runp = bitval;
677*7304104dSAndroid Build Coastguard Worker
678*7304104dSAndroid Build Coastguard Worker while (runp != NULL)
679*7304104dSAndroid Build Coastguard Worker if (runp->type == field && runp->field == name->field)
680*7304104dSAndroid Build Coastguard Worker break;
681*7304104dSAndroid Build Coastguard Worker else
682*7304104dSAndroid Build Coastguard Worker runp = runp->next;
683*7304104dSAndroid Build Coastguard Worker
684*7304104dSAndroid Build Coastguard Worker if (runp == NULL)
685*7304104dSAndroid Build Coastguard Worker {
686*7304104dSAndroid Build Coastguard Worker error (0, 0, "%d: unknown bitfield '%s' used in output format",
687*7304104dSAndroid Build Coastguard Worker i386_lineno - 1, name->field->name);
688*7304104dSAndroid Build Coastguard Worker result = 1;
689*7304104dSAndroid Build Coastguard Worker }
690*7304104dSAndroid Build Coastguard Worker }
691*7304104dSAndroid Build Coastguard Worker
692*7304104dSAndroid Build Coastguard Worker args = args->next;
693*7304104dSAndroid Build Coastguard Worker }
694*7304104dSAndroid Build Coastguard Worker
695*7304104dSAndroid Build Coastguard Worker return result;
696*7304104dSAndroid Build Coastguard Worker }
697*7304104dSAndroid Build Coastguard Worker
698*7304104dSAndroid Build Coastguard Worker
699*7304104dSAndroid Build Coastguard Worker static int
check_bitsused(struct bitvalue * bitval,struct known_bitfield * suffix,struct argument * args)700*7304104dSAndroid Build Coastguard Worker check_bitsused (struct bitvalue *bitval, struct known_bitfield *suffix,
701*7304104dSAndroid Build Coastguard Worker struct argument *args)
702*7304104dSAndroid Build Coastguard Worker {
703*7304104dSAndroid Build Coastguard Worker int result = 0;
704*7304104dSAndroid Build Coastguard Worker
705*7304104dSAndroid Build Coastguard Worker while (bitval != NULL)
706*7304104dSAndroid Build Coastguard Worker {
707*7304104dSAndroid Build Coastguard Worker if (bitval->type == field && bitval->field != NULL
708*7304104dSAndroid Build Coastguard Worker && bitval->field != suffix
709*7304104dSAndroid Build Coastguard Worker /* {w} is handled special. */
710*7304104dSAndroid Build Coastguard Worker && strcmp (bitval->field->name, "w") != 0)
711*7304104dSAndroid Build Coastguard Worker {
712*7304104dSAndroid Build Coastguard Worker struct argument *runp;
713*7304104dSAndroid Build Coastguard Worker for (runp = args; runp != NULL; runp = runp->next)
714*7304104dSAndroid Build Coastguard Worker {
715*7304104dSAndroid Build Coastguard Worker struct argname *name = runp->name;
716*7304104dSAndroid Build Coastguard Worker
717*7304104dSAndroid Build Coastguard Worker while (name != NULL)
718*7304104dSAndroid Build Coastguard Worker if (name->type == nfield && name->field == bitval->field)
719*7304104dSAndroid Build Coastguard Worker break;
720*7304104dSAndroid Build Coastguard Worker else
721*7304104dSAndroid Build Coastguard Worker name = name->next;
722*7304104dSAndroid Build Coastguard Worker
723*7304104dSAndroid Build Coastguard Worker if (name != NULL)
724*7304104dSAndroid Build Coastguard Worker break;
725*7304104dSAndroid Build Coastguard Worker }
726*7304104dSAndroid Build Coastguard Worker
727*7304104dSAndroid Build Coastguard Worker #if 0
728*7304104dSAndroid Build Coastguard Worker if (runp == NULL)
729*7304104dSAndroid Build Coastguard Worker {
730*7304104dSAndroid Build Coastguard Worker error (0, 0, "%d: bitfield '%s' not used",
731*7304104dSAndroid Build Coastguard Worker i386_lineno - 1, bitval->field->name);
732*7304104dSAndroid Build Coastguard Worker result = 1;
733*7304104dSAndroid Build Coastguard Worker }
734*7304104dSAndroid Build Coastguard Worker #endif
735*7304104dSAndroid Build Coastguard Worker }
736*7304104dSAndroid Build Coastguard Worker
737*7304104dSAndroid Build Coastguard Worker bitval = bitval->next;
738*7304104dSAndroid Build Coastguard Worker }
739*7304104dSAndroid Build Coastguard Worker
740*7304104dSAndroid Build Coastguard Worker return result;
741*7304104dSAndroid Build Coastguard Worker }
742*7304104dSAndroid Build Coastguard Worker
743*7304104dSAndroid Build Coastguard Worker
744*7304104dSAndroid Build Coastguard Worker static struct argname *
combine(struct argname * name)745*7304104dSAndroid Build Coastguard Worker combine (struct argname *name)
746*7304104dSAndroid Build Coastguard Worker {
747*7304104dSAndroid Build Coastguard Worker struct argname *last_str = NULL;
748*7304104dSAndroid Build Coastguard Worker for (struct argname *runp = name; runp != NULL; runp = runp->next)
749*7304104dSAndroid Build Coastguard Worker {
750*7304104dSAndroid Build Coastguard Worker if (runp->type == string)
751*7304104dSAndroid Build Coastguard Worker {
752*7304104dSAndroid Build Coastguard Worker if (last_str == NULL)
753*7304104dSAndroid Build Coastguard Worker last_str = runp;
754*7304104dSAndroid Build Coastguard Worker else
755*7304104dSAndroid Build Coastguard Worker {
756*7304104dSAndroid Build Coastguard Worker last_str->str = xrealloc (last_str->str,
757*7304104dSAndroid Build Coastguard Worker strlen (last_str->str)
758*7304104dSAndroid Build Coastguard Worker + strlen (runp->str) + 1);
759*7304104dSAndroid Build Coastguard Worker strcat (last_str->str, runp->str);
760*7304104dSAndroid Build Coastguard Worker last_str->next = runp->next;
761*7304104dSAndroid Build Coastguard Worker }
762*7304104dSAndroid Build Coastguard Worker }
763*7304104dSAndroid Build Coastguard Worker else
764*7304104dSAndroid Build Coastguard Worker last_str = NULL;
765*7304104dSAndroid Build Coastguard Worker }
766*7304104dSAndroid Build Coastguard Worker return name;
767*7304104dSAndroid Build Coastguard Worker }
768*7304104dSAndroid Build Coastguard Worker
769*7304104dSAndroid Build Coastguard Worker
770*7304104dSAndroid Build Coastguard Worker #define obstack_grow_str(ob, str) obstack_grow (ob, str, strlen (str))
771*7304104dSAndroid Build Coastguard Worker
772*7304104dSAndroid Build Coastguard Worker
773*7304104dSAndroid Build Coastguard Worker static void
fillin_arg(struct bitvalue * bytes,struct argname * name,struct instruction * instr,int n)774*7304104dSAndroid Build Coastguard Worker fillin_arg (struct bitvalue *bytes, struct argname *name,
775*7304104dSAndroid Build Coastguard Worker struct instruction *instr, int n)
776*7304104dSAndroid Build Coastguard Worker {
777*7304104dSAndroid Build Coastguard Worker static struct obstack ob;
778*7304104dSAndroid Build Coastguard Worker static int initialized;
779*7304104dSAndroid Build Coastguard Worker if (! initialized)
780*7304104dSAndroid Build Coastguard Worker {
781*7304104dSAndroid Build Coastguard Worker initialized = 1;
782*7304104dSAndroid Build Coastguard Worker obstack_init (&ob);
783*7304104dSAndroid Build Coastguard Worker }
784*7304104dSAndroid Build Coastguard Worker
785*7304104dSAndroid Build Coastguard Worker struct argname *runp = name;
786*7304104dSAndroid Build Coastguard Worker int cnt = 0;
787*7304104dSAndroid Build Coastguard Worker while (runp != NULL)
788*7304104dSAndroid Build Coastguard Worker {
789*7304104dSAndroid Build Coastguard Worker /* We ignore strings in the function name. */
790*7304104dSAndroid Build Coastguard Worker if (runp->type == string)
791*7304104dSAndroid Build Coastguard Worker {
792*7304104dSAndroid Build Coastguard Worker if (instr->operands[n].str != NULL)
793*7304104dSAndroid Build Coastguard Worker error (EXIT_FAILURE, 0,
794*7304104dSAndroid Build Coastguard Worker "%d: cannot have more than one string parameter",
795*7304104dSAndroid Build Coastguard Worker i386_lineno - 1);
796*7304104dSAndroid Build Coastguard Worker
797*7304104dSAndroid Build Coastguard Worker instr->operands[n].str = runp->str;
798*7304104dSAndroid Build Coastguard Worker }
799*7304104dSAndroid Build Coastguard Worker else
800*7304104dSAndroid Build Coastguard Worker {
801*7304104dSAndroid Build Coastguard Worker assert (runp->type == nfield);
802*7304104dSAndroid Build Coastguard Worker
803*7304104dSAndroid Build Coastguard Worker /* Construct the function name. */
804*7304104dSAndroid Build Coastguard Worker if (cnt++ > 0)
805*7304104dSAndroid Build Coastguard Worker obstack_1grow (&ob, '$');
806*7304104dSAndroid Build Coastguard Worker
807*7304104dSAndroid Build Coastguard Worker if (runp->field == NULL)
808*7304104dSAndroid Build Coastguard Worker /* Add some string which contains invalid characters. */
809*7304104dSAndroid Build Coastguard Worker obstack_grow_str (&ob, "!!!INVALID!!!");
810*7304104dSAndroid Build Coastguard Worker else
811*7304104dSAndroid Build Coastguard Worker {
812*7304104dSAndroid Build Coastguard Worker char *fieldname = runp->field->name;
813*7304104dSAndroid Build Coastguard Worker
814*7304104dSAndroid Build Coastguard Worker struct synonym search = { .from = fieldname };
815*7304104dSAndroid Build Coastguard Worker
816*7304104dSAndroid Build Coastguard Worker struct synonym **res = tfind (&search, &synonyms, compare_syn);
817*7304104dSAndroid Build Coastguard Worker if (res != NULL)
818*7304104dSAndroid Build Coastguard Worker fieldname = (*res)->to;
819*7304104dSAndroid Build Coastguard Worker
820*7304104dSAndroid Build Coastguard Worker obstack_grow_str (&ob, fieldname);
821*7304104dSAndroid Build Coastguard Worker }
822*7304104dSAndroid Build Coastguard Worker
823*7304104dSAndroid Build Coastguard Worker /* Now compute the bit offset of the field. */
824*7304104dSAndroid Build Coastguard Worker struct bitvalue *b = bytes;
825*7304104dSAndroid Build Coastguard Worker int bitoff = 0;
826*7304104dSAndroid Build Coastguard Worker if (runp->field != NULL)
827*7304104dSAndroid Build Coastguard Worker while (b != NULL)
828*7304104dSAndroid Build Coastguard Worker {
829*7304104dSAndroid Build Coastguard Worker if (b->type == field && b->field != NULL)
830*7304104dSAndroid Build Coastguard Worker {
831*7304104dSAndroid Build Coastguard Worker if (strcmp (b->field->name, runp->field->name) == 0)
832*7304104dSAndroid Build Coastguard Worker break;
833*7304104dSAndroid Build Coastguard Worker bitoff += b->field->bits;
834*7304104dSAndroid Build Coastguard Worker }
835*7304104dSAndroid Build Coastguard Worker else
836*7304104dSAndroid Build Coastguard Worker ++bitoff;
837*7304104dSAndroid Build Coastguard Worker
838*7304104dSAndroid Build Coastguard Worker b = b->next;
839*7304104dSAndroid Build Coastguard Worker }
840*7304104dSAndroid Build Coastguard Worker if (instr->operands[n].off1 == 0)
841*7304104dSAndroid Build Coastguard Worker instr->operands[n].off1 = bitoff;
842*7304104dSAndroid Build Coastguard Worker else if (instr->operands[n].off2 == 0)
843*7304104dSAndroid Build Coastguard Worker instr->operands[n].off2 = bitoff;
844*7304104dSAndroid Build Coastguard Worker else if (instr->operands[n].off3 == 0)
845*7304104dSAndroid Build Coastguard Worker instr->operands[n].off3 = bitoff;
846*7304104dSAndroid Build Coastguard Worker else
847*7304104dSAndroid Build Coastguard Worker error (EXIT_FAILURE, 0,
848*7304104dSAndroid Build Coastguard Worker "%d: cannot have more than three fields in parameter",
849*7304104dSAndroid Build Coastguard Worker i386_lineno - 1);
850*7304104dSAndroid Build Coastguard Worker
851*7304104dSAndroid Build Coastguard Worker if (runp->field != NULL
852*7304104dSAndroid Build Coastguard Worker && strncasecmp (runp->field->name, "mod", 3) == 0)
853*7304104dSAndroid Build Coastguard Worker instr->modrm = 1;
854*7304104dSAndroid Build Coastguard Worker }
855*7304104dSAndroid Build Coastguard Worker
856*7304104dSAndroid Build Coastguard Worker runp = runp->next;
857*7304104dSAndroid Build Coastguard Worker }
858*7304104dSAndroid Build Coastguard Worker if (obstack_object_size (&ob) == 0)
859*7304104dSAndroid Build Coastguard Worker obstack_grow_str (&ob, "string");
860*7304104dSAndroid Build Coastguard Worker obstack_1grow (&ob, '\0');
861*7304104dSAndroid Build Coastguard Worker char *fct = obstack_finish (&ob);
862*7304104dSAndroid Build Coastguard Worker
863*7304104dSAndroid Build Coastguard Worker instr->operands[n].fct = fct;
864*7304104dSAndroid Build Coastguard Worker }
865*7304104dSAndroid Build Coastguard Worker
866*7304104dSAndroid Build Coastguard Worker
867*7304104dSAndroid Build Coastguard Worker #if 0
868*7304104dSAndroid Build Coastguard Worker static void
869*7304104dSAndroid Build Coastguard Worker nameout (const void *nodep, VISIT value, int level)
870*7304104dSAndroid Build Coastguard Worker {
871*7304104dSAndroid Build Coastguard Worker if (value == leaf || value == postorder)
872*7304104dSAndroid Build Coastguard Worker printf (" %s\n", *(const char **) nodep);
873*7304104dSAndroid Build Coastguard Worker }
874*7304104dSAndroid Build Coastguard Worker #endif
875*7304104dSAndroid Build Coastguard Worker
876*7304104dSAndroid Build Coastguard Worker
877*7304104dSAndroid Build Coastguard Worker static int
compare_argstring(const void * p1,const void * p2)878*7304104dSAndroid Build Coastguard Worker compare_argstring (const void *p1, const void *p2)
879*7304104dSAndroid Build Coastguard Worker {
880*7304104dSAndroid Build Coastguard Worker const struct argstring *a1 = (const struct argstring *) p1;
881*7304104dSAndroid Build Coastguard Worker const struct argstring *a2 = (const struct argstring *) p2;
882*7304104dSAndroid Build Coastguard Worker
883*7304104dSAndroid Build Coastguard Worker return strcmp (a1->str, a2->str);
884*7304104dSAndroid Build Coastguard Worker }
885*7304104dSAndroid Build Coastguard Worker
886*7304104dSAndroid Build Coastguard Worker
887*7304104dSAndroid Build Coastguard Worker static int maxoff[3][3];
888*7304104dSAndroid Build Coastguard Worker static int minoff[3][3] = { { 1000, 1000, 1000 },
889*7304104dSAndroid Build Coastguard Worker { 1000, 1000, 1000 },
890*7304104dSAndroid Build Coastguard Worker { 1000, 1000, 1000 } };
891*7304104dSAndroid Build Coastguard Worker static int nbitoff[3][3];
892*7304104dSAndroid Build Coastguard Worker static void *fct_names[3];
893*7304104dSAndroid Build Coastguard Worker static int nbitfct[3];
894*7304104dSAndroid Build Coastguard Worker static int nbitsuf;
895*7304104dSAndroid Build Coastguard Worker static void *strs[3];
896*7304104dSAndroid Build Coastguard Worker static int nbitstr[3];
897*7304104dSAndroid Build Coastguard Worker static int total_bits = 2; // Already counted the rep/repe bits.
898*7304104dSAndroid Build Coastguard Worker
899*7304104dSAndroid Build Coastguard Worker static void
find_numbers(void)900*7304104dSAndroid Build Coastguard Worker find_numbers (void)
901*7304104dSAndroid Build Coastguard Worker {
902*7304104dSAndroid Build Coastguard Worker int nfct_names[3] = { 0, 0, 0 };
903*7304104dSAndroid Build Coastguard Worker int nstrs[3] = { 0, 0, 0 };
904*7304104dSAndroid Build Coastguard Worker
905*7304104dSAndroid Build Coastguard Worker /* We reverse the order of the instruction list while processing it.
906*7304104dSAndroid Build Coastguard Worker Later phases need it in the order in which the input file has
907*7304104dSAndroid Build Coastguard Worker them. */
908*7304104dSAndroid Build Coastguard Worker struct instruction *reversed = NULL;
909*7304104dSAndroid Build Coastguard Worker
910*7304104dSAndroid Build Coastguard Worker struct instruction *runp = instructions;
911*7304104dSAndroid Build Coastguard Worker while (runp != NULL)
912*7304104dSAndroid Build Coastguard Worker {
913*7304104dSAndroid Build Coastguard Worker for (int i = 0; i < 3; ++i)
914*7304104dSAndroid Build Coastguard Worker if (runp->operands[i].fct != NULL)
915*7304104dSAndroid Build Coastguard Worker {
916*7304104dSAndroid Build Coastguard Worker struct argstring search = { .str = runp->operands[i].fct };
917*7304104dSAndroid Build Coastguard Worker if (tfind (&search, &fct_names[i], compare_argstring) == NULL)
918*7304104dSAndroid Build Coastguard Worker {
919*7304104dSAndroid Build Coastguard Worker struct argstring *newp = xmalloc (sizeof (*newp));
920*7304104dSAndroid Build Coastguard Worker newp->str = runp->operands[i].fct;
921*7304104dSAndroid Build Coastguard Worker newp->idx = 0;
922*7304104dSAndroid Build Coastguard Worker if (tsearch (newp, &fct_names[i], compare_argstring) == NULL)
923*7304104dSAndroid Build Coastguard Worker error (EXIT_FAILURE, errno, "tsearch");
924*7304104dSAndroid Build Coastguard Worker ++nfct_names[i];
925*7304104dSAndroid Build Coastguard Worker }
926*7304104dSAndroid Build Coastguard Worker
927*7304104dSAndroid Build Coastguard Worker if (runp->operands[i].str != NULL)
928*7304104dSAndroid Build Coastguard Worker {
929*7304104dSAndroid Build Coastguard Worker search.str = runp->operands[i].str;
930*7304104dSAndroid Build Coastguard Worker if (tfind (&search, &strs[i], compare_argstring) == NULL)
931*7304104dSAndroid Build Coastguard Worker {
932*7304104dSAndroid Build Coastguard Worker struct argstring *newp = xmalloc (sizeof (*newp));
933*7304104dSAndroid Build Coastguard Worker newp->str = runp->operands[i].str;
934*7304104dSAndroid Build Coastguard Worker newp->idx = 0;
935*7304104dSAndroid Build Coastguard Worker if (tsearch (newp, &strs[i], compare_argstring) == NULL)
936*7304104dSAndroid Build Coastguard Worker error (EXIT_FAILURE, errno, "tsearch");
937*7304104dSAndroid Build Coastguard Worker ++nstrs[i];
938*7304104dSAndroid Build Coastguard Worker }
939*7304104dSAndroid Build Coastguard Worker }
940*7304104dSAndroid Build Coastguard Worker
941*7304104dSAndroid Build Coastguard Worker maxoff[i][0] = MAX (maxoff[i][0], runp->operands[i].off1);
942*7304104dSAndroid Build Coastguard Worker maxoff[i][1] = MAX (maxoff[i][1], runp->operands[i].off2);
943*7304104dSAndroid Build Coastguard Worker maxoff[i][2] = MAX (maxoff[i][2], runp->operands[i].off3);
944*7304104dSAndroid Build Coastguard Worker
945*7304104dSAndroid Build Coastguard Worker if (runp->operands[i].off1 > 0)
946*7304104dSAndroid Build Coastguard Worker minoff[i][0] = MIN (minoff[i][0], runp->operands[i].off1);
947*7304104dSAndroid Build Coastguard Worker if (runp->operands[i].off2 > 0)
948*7304104dSAndroid Build Coastguard Worker minoff[i][1] = MIN (minoff[i][1], runp->operands[i].off2);
949*7304104dSAndroid Build Coastguard Worker if (runp->operands[i].off3 > 0)
950*7304104dSAndroid Build Coastguard Worker minoff[i][2] = MIN (minoff[i][2], runp->operands[i].off3);
951*7304104dSAndroid Build Coastguard Worker }
952*7304104dSAndroid Build Coastguard Worker
953*7304104dSAndroid Build Coastguard Worker struct instruction *old = runp;
954*7304104dSAndroid Build Coastguard Worker runp = runp->next;
955*7304104dSAndroid Build Coastguard Worker
956*7304104dSAndroid Build Coastguard Worker old->next = reversed;
957*7304104dSAndroid Build Coastguard Worker reversed = old;
958*7304104dSAndroid Build Coastguard Worker }
959*7304104dSAndroid Build Coastguard Worker instructions = reversed;
960*7304104dSAndroid Build Coastguard Worker
961*7304104dSAndroid Build Coastguard Worker int d;
962*7304104dSAndroid Build Coastguard Worker int c;
963*7304104dSAndroid Build Coastguard Worker for (int i = 0; i < 3; ++i)
964*7304104dSAndroid Build Coastguard Worker {
965*7304104dSAndroid Build Coastguard Worker // printf ("min1 = %d, min2 = %d, min3 = %d\n", minoff[i][0], minoff[i][1], minoff[i][2]);
966*7304104dSAndroid Build Coastguard Worker // printf ("max1 = %d, max2 = %d, max3 = %d\n", maxoff[i][0], maxoff[i][1], maxoff[i][2]);
967*7304104dSAndroid Build Coastguard Worker
968*7304104dSAndroid Build Coastguard Worker if (minoff[i][0] == 1000)
969*7304104dSAndroid Build Coastguard Worker nbitoff[i][0] = 0;
970*7304104dSAndroid Build Coastguard Worker else
971*7304104dSAndroid Build Coastguard Worker {
972*7304104dSAndroid Build Coastguard Worker nbitoff[i][0] = 1;
973*7304104dSAndroid Build Coastguard Worker d = maxoff[i][0] - minoff[i][0];
974*7304104dSAndroid Build Coastguard Worker c = 1;
975*7304104dSAndroid Build Coastguard Worker while (c < d)
976*7304104dSAndroid Build Coastguard Worker {
977*7304104dSAndroid Build Coastguard Worker ++nbitoff[i][0];
978*7304104dSAndroid Build Coastguard Worker c *= 2;
979*7304104dSAndroid Build Coastguard Worker }
980*7304104dSAndroid Build Coastguard Worker total_bits += nbitoff[i][0];
981*7304104dSAndroid Build Coastguard Worker }
982*7304104dSAndroid Build Coastguard Worker
983*7304104dSAndroid Build Coastguard Worker if (minoff[i][1] == 1000)
984*7304104dSAndroid Build Coastguard Worker nbitoff[i][1] = 0;
985*7304104dSAndroid Build Coastguard Worker else
986*7304104dSAndroid Build Coastguard Worker {
987*7304104dSAndroid Build Coastguard Worker nbitoff[i][1] = 1;
988*7304104dSAndroid Build Coastguard Worker d = maxoff[i][1] - minoff[i][1];
989*7304104dSAndroid Build Coastguard Worker c = 1;
990*7304104dSAndroid Build Coastguard Worker while (c < d)
991*7304104dSAndroid Build Coastguard Worker {
992*7304104dSAndroid Build Coastguard Worker ++nbitoff[i][1];
993*7304104dSAndroid Build Coastguard Worker c *= 2;
994*7304104dSAndroid Build Coastguard Worker }
995*7304104dSAndroid Build Coastguard Worker total_bits += nbitoff[i][1];
996*7304104dSAndroid Build Coastguard Worker }
997*7304104dSAndroid Build Coastguard Worker
998*7304104dSAndroid Build Coastguard Worker if (minoff[i][2] == 1000)
999*7304104dSAndroid Build Coastguard Worker nbitoff[i][2] = 0;
1000*7304104dSAndroid Build Coastguard Worker else
1001*7304104dSAndroid Build Coastguard Worker {
1002*7304104dSAndroid Build Coastguard Worker nbitoff[i][2] = 1;
1003*7304104dSAndroid Build Coastguard Worker d = maxoff[i][2] - minoff[i][2];
1004*7304104dSAndroid Build Coastguard Worker c = 1;
1005*7304104dSAndroid Build Coastguard Worker while (c < d)
1006*7304104dSAndroid Build Coastguard Worker {
1007*7304104dSAndroid Build Coastguard Worker ++nbitoff[i][2];
1008*7304104dSAndroid Build Coastguard Worker c *= 2;
1009*7304104dSAndroid Build Coastguard Worker }
1010*7304104dSAndroid Build Coastguard Worker total_bits += nbitoff[i][2];
1011*7304104dSAndroid Build Coastguard Worker }
1012*7304104dSAndroid Build Coastguard Worker // printf ("off1 = %d, off2 = %d, off3 = %d\n", nbitoff[i][0], nbitoff[i][1], nbitoff[i][2]);
1013*7304104dSAndroid Build Coastguard Worker
1014*7304104dSAndroid Build Coastguard Worker nbitfct[i] = 1;
1015*7304104dSAndroid Build Coastguard Worker d = nfct_names[i];
1016*7304104dSAndroid Build Coastguard Worker c = 1;
1017*7304104dSAndroid Build Coastguard Worker while (c < d)
1018*7304104dSAndroid Build Coastguard Worker {
1019*7304104dSAndroid Build Coastguard Worker ++nbitfct[i];
1020*7304104dSAndroid Build Coastguard Worker c *= 2;
1021*7304104dSAndroid Build Coastguard Worker }
1022*7304104dSAndroid Build Coastguard Worker total_bits += nbitfct[i];
1023*7304104dSAndroid Build Coastguard Worker // printf ("%d fct[%d], %d bits\n", nfct_names[i], i, nbitfct[i]);
1024*7304104dSAndroid Build Coastguard Worker
1025*7304104dSAndroid Build Coastguard Worker if (nstrs[i] != 0)
1026*7304104dSAndroid Build Coastguard Worker {
1027*7304104dSAndroid Build Coastguard Worker nbitstr[i] = 1;
1028*7304104dSAndroid Build Coastguard Worker d = nstrs[i];
1029*7304104dSAndroid Build Coastguard Worker c = 1;
1030*7304104dSAndroid Build Coastguard Worker while (c < d)
1031*7304104dSAndroid Build Coastguard Worker {
1032*7304104dSAndroid Build Coastguard Worker ++nbitstr[i];
1033*7304104dSAndroid Build Coastguard Worker c *= 2;
1034*7304104dSAndroid Build Coastguard Worker }
1035*7304104dSAndroid Build Coastguard Worker total_bits += nbitstr[i];
1036*7304104dSAndroid Build Coastguard Worker }
1037*7304104dSAndroid Build Coastguard Worker
1038*7304104dSAndroid Build Coastguard Worker // twalk (fct_names[i], nameout);
1039*7304104dSAndroid Build Coastguard Worker }
1040*7304104dSAndroid Build Coastguard Worker
1041*7304104dSAndroid Build Coastguard Worker nbitsuf = 0;
1042*7304104dSAndroid Build Coastguard Worker d = nsuffixes;
1043*7304104dSAndroid Build Coastguard Worker c = 1;
1044*7304104dSAndroid Build Coastguard Worker while (c < d)
1045*7304104dSAndroid Build Coastguard Worker {
1046*7304104dSAndroid Build Coastguard Worker ++nbitsuf;
1047*7304104dSAndroid Build Coastguard Worker c *= 2;
1048*7304104dSAndroid Build Coastguard Worker }
1049*7304104dSAndroid Build Coastguard Worker total_bits += nbitsuf;
1050*7304104dSAndroid Build Coastguard Worker // printf ("%d suffixes, %d bits\n", nsuffixes, nbitsuf);
1051*7304104dSAndroid Build Coastguard Worker }
1052*7304104dSAndroid Build Coastguard Worker
1053*7304104dSAndroid Build Coastguard Worker
1054*7304104dSAndroid Build Coastguard Worker static int
compare_syn(const void * p1,const void * p2)1055*7304104dSAndroid Build Coastguard Worker compare_syn (const void *p1, const void *p2)
1056*7304104dSAndroid Build Coastguard Worker {
1057*7304104dSAndroid Build Coastguard Worker const struct synonym *s1 = (const struct synonym *) p1;
1058*7304104dSAndroid Build Coastguard Worker const struct synonym *s2 = (const struct synonym *) p2;
1059*7304104dSAndroid Build Coastguard Worker
1060*7304104dSAndroid Build Coastguard Worker return strcmp (s1->from, s2->from);
1061*7304104dSAndroid Build Coastguard Worker }
1062*7304104dSAndroid Build Coastguard Worker
1063*7304104dSAndroid Build Coastguard Worker
1064*7304104dSAndroid Build Coastguard Worker static int
compare_suf(const void * p1,const void * p2)1065*7304104dSAndroid Build Coastguard Worker compare_suf (const void *p1, const void *p2)
1066*7304104dSAndroid Build Coastguard Worker {
1067*7304104dSAndroid Build Coastguard Worker const struct suffix *s1 = (const struct suffix *) p1;
1068*7304104dSAndroid Build Coastguard Worker const struct suffix *s2 = (const struct suffix *) p2;
1069*7304104dSAndroid Build Coastguard Worker
1070*7304104dSAndroid Build Coastguard Worker return strcmp (s1->name, s2->name);
1071*7304104dSAndroid Build Coastguard Worker }
1072*7304104dSAndroid Build Coastguard Worker
1073*7304104dSAndroid Build Coastguard Worker
1074*7304104dSAndroid Build Coastguard Worker static int count_op_str;
1075*7304104dSAndroid Build Coastguard Worker static int off_op_str;
1076*7304104dSAndroid Build Coastguard Worker static void
print_op_str(const void * nodep,VISIT value,int level)1077*7304104dSAndroid Build Coastguard Worker print_op_str (const void *nodep, VISIT value,
1078*7304104dSAndroid Build Coastguard Worker int level __attribute__ ((unused)))
1079*7304104dSAndroid Build Coastguard Worker {
1080*7304104dSAndroid Build Coastguard Worker if (value == leaf || value == postorder)
1081*7304104dSAndroid Build Coastguard Worker {
1082*7304104dSAndroid Build Coastguard Worker const char *str = (*(struct argstring **) nodep)->str;
1083*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "%s\n \"%s",
1084*7304104dSAndroid Build Coastguard Worker count_op_str == 0 ? "" : "\\0\"", str);
1085*7304104dSAndroid Build Coastguard Worker (*(struct argstring **) nodep)->idx = ++count_op_str;
1086*7304104dSAndroid Build Coastguard Worker (*(struct argstring **) nodep)->off = off_op_str;
1087*7304104dSAndroid Build Coastguard Worker off_op_str += strlen (str) + 1;
1088*7304104dSAndroid Build Coastguard Worker }
1089*7304104dSAndroid Build Coastguard Worker }
1090*7304104dSAndroid Build Coastguard Worker
1091*7304104dSAndroid Build Coastguard Worker
1092*7304104dSAndroid Build Coastguard Worker static void
print_op_str_idx(const void * nodep,VISIT value,int level)1093*7304104dSAndroid Build Coastguard Worker print_op_str_idx (const void *nodep, VISIT value,
1094*7304104dSAndroid Build Coastguard Worker int level __attribute__ ((unused)))
1095*7304104dSAndroid Build Coastguard Worker {
1096*7304104dSAndroid Build Coastguard Worker if (value == leaf || value == postorder)
1097*7304104dSAndroid Build Coastguard Worker printf (" %d,\n", (*(struct argstring **) nodep)->off);
1098*7304104dSAndroid Build Coastguard Worker }
1099*7304104dSAndroid Build Coastguard Worker
1100*7304104dSAndroid Build Coastguard Worker
1101*7304104dSAndroid Build Coastguard Worker static void
print_op_fct(const void * nodep,VISIT value,int level)1102*7304104dSAndroid Build Coastguard Worker print_op_fct (const void *nodep, VISIT value,
1103*7304104dSAndroid Build Coastguard Worker int level __attribute__ ((unused)))
1104*7304104dSAndroid Build Coastguard Worker {
1105*7304104dSAndroid Build Coastguard Worker if (value == leaf || value == postorder)
1106*7304104dSAndroid Build Coastguard Worker {
1107*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " FCT_%s,\n", (*(struct argstring **) nodep)->str);
1108*7304104dSAndroid Build Coastguard Worker (*(struct argstring **) nodep)->idx = ++count_op_str;
1109*7304104dSAndroid Build Coastguard Worker }
1110*7304104dSAndroid Build Coastguard Worker }
1111*7304104dSAndroid Build Coastguard Worker
1112*7304104dSAndroid Build Coastguard Worker static void
instrtable_out(void)1113*7304104dSAndroid Build Coastguard Worker instrtable_out (void)
1114*7304104dSAndroid Build Coastguard Worker {
1115*7304104dSAndroid Build Coastguard Worker find_numbers ();
1116*7304104dSAndroid Build Coastguard Worker
1117*7304104dSAndroid Build Coastguard Worker #if 0
1118*7304104dSAndroid Build Coastguard Worker create_mnemonic_table ();
1119*7304104dSAndroid Build Coastguard Worker
1120*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "#define MNEMONIC_BITS %zu\n", best_mnemonic_bits);
1121*7304104dSAndroid Build Coastguard Worker #else
1122*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "#define MNEMONIC_BITS %ld\n",
1123*7304104dSAndroid Build Coastguard Worker lrint (ceil (log2 (MNE_COUNT))));
1124*7304104dSAndroid Build Coastguard Worker #endif
1125*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "#define SUFFIX_BITS %d\n", nbitsuf);
1126*7304104dSAndroid Build Coastguard Worker for (int i = 0; i < 3; ++i)
1127*7304104dSAndroid Build Coastguard Worker {
1128*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "#define FCT%d_BITS %d\n", i + 1, nbitfct[i]);
1129*7304104dSAndroid Build Coastguard Worker if (nbitstr[i] != 0)
1130*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "#define STR%d_BITS %d\n", i + 1, nbitstr[i]);
1131*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "#define OFF%d_1_BITS %d\n", i + 1, nbitoff[i][0]);
1132*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "#define OFF%d_1_BIAS %d\n", i + 1, minoff[i][0]);
1133*7304104dSAndroid Build Coastguard Worker if (nbitoff[i][1] != 0)
1134*7304104dSAndroid Build Coastguard Worker {
1135*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "#define OFF%d_2_BITS %d\n", i + 1, nbitoff[i][1]);
1136*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "#define OFF%d_2_BIAS %d\n", i + 1, minoff[i][1]);
1137*7304104dSAndroid Build Coastguard Worker }
1138*7304104dSAndroid Build Coastguard Worker if (nbitoff[i][2] != 0)
1139*7304104dSAndroid Build Coastguard Worker {
1140*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "#define OFF%d_3_BITS %d\n", i + 1, nbitoff[i][2]);
1141*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "#define OFF%d_3_BIAS %d\n", i + 1, minoff[i][2]);
1142*7304104dSAndroid Build Coastguard Worker }
1143*7304104dSAndroid Build Coastguard Worker }
1144*7304104dSAndroid Build Coastguard Worker
1145*7304104dSAndroid Build Coastguard Worker fputs ("\n#include <i386_data.h>\n\n", outfile);
1146*7304104dSAndroid Build Coastguard Worker
1147*7304104dSAndroid Build Coastguard Worker
1148*7304104dSAndroid Build Coastguard Worker #define APPEND(a, b) APPEND_ (a, b)
1149*7304104dSAndroid Build Coastguard Worker #define APPEND_(a, b) a##b
1150*7304104dSAndroid Build Coastguard Worker #define EMIT_SUFFIX(suf) \
1151*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "#define suffix_%s %d\n", #suf, APPEND (suffix_, suf))
1152*7304104dSAndroid Build Coastguard Worker EMIT_SUFFIX (none);
1153*7304104dSAndroid Build Coastguard Worker EMIT_SUFFIX (w);
1154*7304104dSAndroid Build Coastguard Worker EMIT_SUFFIX (w0);
1155*7304104dSAndroid Build Coastguard Worker EMIT_SUFFIX (W);
1156*7304104dSAndroid Build Coastguard Worker EMIT_SUFFIX (tttn);
1157*7304104dSAndroid Build Coastguard Worker EMIT_SUFFIX (D);
1158*7304104dSAndroid Build Coastguard Worker EMIT_SUFFIX (w1);
1159*7304104dSAndroid Build Coastguard Worker EMIT_SUFFIX (W1);
1160*7304104dSAndroid Build Coastguard Worker
1161*7304104dSAndroid Build Coastguard Worker fputc_unlocked ('\n', outfile);
1162*7304104dSAndroid Build Coastguard Worker
1163*7304104dSAndroid Build Coastguard Worker for (int i = 0; i < 3; ++i)
1164*7304104dSAndroid Build Coastguard Worker {
1165*7304104dSAndroid Build Coastguard Worker /* Functions. */
1166*7304104dSAndroid Build Coastguard Worker count_op_str = 0;
1167*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "static const opfct_t op%d_fct[] =\n{\n NULL,\n",
1168*7304104dSAndroid Build Coastguard Worker i + 1);
1169*7304104dSAndroid Build Coastguard Worker twalk (fct_names[i], print_op_fct);
1170*7304104dSAndroid Build Coastguard Worker fputs ("};\n", outfile);
1171*7304104dSAndroid Build Coastguard Worker
1172*7304104dSAndroid Build Coastguard Worker /* The operand strings. */
1173*7304104dSAndroid Build Coastguard Worker if (nbitstr[i] != 0)
1174*7304104dSAndroid Build Coastguard Worker {
1175*7304104dSAndroid Build Coastguard Worker count_op_str = 0;
1176*7304104dSAndroid Build Coastguard Worker off_op_str = 0;
1177*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "static const char op%d_str[] =", i + 1);
1178*7304104dSAndroid Build Coastguard Worker twalk (strs[i], print_op_str);
1179*7304104dSAndroid Build Coastguard Worker fputs ("\";\n", outfile);
1180*7304104dSAndroid Build Coastguard Worker
1181*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "static const uint8_t op%d_str_idx[] = {\n",
1182*7304104dSAndroid Build Coastguard Worker i + 1);
1183*7304104dSAndroid Build Coastguard Worker twalk (strs[i], print_op_str_idx);
1184*7304104dSAndroid Build Coastguard Worker fputs ("};\n", outfile);
1185*7304104dSAndroid Build Coastguard Worker }
1186*7304104dSAndroid Build Coastguard Worker }
1187*7304104dSAndroid Build Coastguard Worker
1188*7304104dSAndroid Build Coastguard Worker
1189*7304104dSAndroid Build Coastguard Worker fputs ("static const struct instr_enc instrtab[] =\n{\n", outfile);
1190*7304104dSAndroid Build Coastguard Worker struct instruction *instr;
1191*7304104dSAndroid Build Coastguard Worker for (instr = instructions; instr != NULL; instr = instr->next)
1192*7304104dSAndroid Build Coastguard Worker {
1193*7304104dSAndroid Build Coastguard Worker fputs (" {", outfile);
1194*7304104dSAndroid Build Coastguard Worker if (instr->mnemonic == (void *) -1l)
1195*7304104dSAndroid Build Coastguard Worker fputs (" .mnemonic = MNE_INVALID,", outfile);
1196*7304104dSAndroid Build Coastguard Worker else
1197*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " .mnemonic = MNE_%s,", instr->mnemonic);
1198*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " .rep = %d,", instr->rep);
1199*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " .repe = %d,", instr->repe);
1200*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " .suffix = %d,", instr->suffix);
1201*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " .modrm = %d,", instr->modrm);
1202*7304104dSAndroid Build Coastguard Worker
1203*7304104dSAndroid Build Coastguard Worker for (int i = 0; i < 3; ++i)
1204*7304104dSAndroid Build Coastguard Worker {
1205*7304104dSAndroid Build Coastguard Worker int idx = 0;
1206*7304104dSAndroid Build Coastguard Worker if (instr->operands[i].fct != NULL)
1207*7304104dSAndroid Build Coastguard Worker {
1208*7304104dSAndroid Build Coastguard Worker struct argstring search = { .str = instr->operands[i].fct };
1209*7304104dSAndroid Build Coastguard Worker struct argstring **res = tfind (&search, &fct_names[i],
1210*7304104dSAndroid Build Coastguard Worker compare_argstring);
1211*7304104dSAndroid Build Coastguard Worker assert (res != NULL);
1212*7304104dSAndroid Build Coastguard Worker idx = (*res)->idx;
1213*7304104dSAndroid Build Coastguard Worker }
1214*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " .fct%d = %d,", i + 1, idx);
1215*7304104dSAndroid Build Coastguard Worker
1216*7304104dSAndroid Build Coastguard Worker idx = 0;
1217*7304104dSAndroid Build Coastguard Worker if (instr->operands[i].str != NULL)
1218*7304104dSAndroid Build Coastguard Worker {
1219*7304104dSAndroid Build Coastguard Worker struct argstring search = { .str = instr->operands[i].str };
1220*7304104dSAndroid Build Coastguard Worker struct argstring **res = tfind (&search, &strs[i],
1221*7304104dSAndroid Build Coastguard Worker compare_argstring);
1222*7304104dSAndroid Build Coastguard Worker assert (res != NULL);
1223*7304104dSAndroid Build Coastguard Worker idx = (*res)->idx;
1224*7304104dSAndroid Build Coastguard Worker }
1225*7304104dSAndroid Build Coastguard Worker if (nbitstr[i] != 0)
1226*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " .str%d = %d,", i + 1, idx);
1227*7304104dSAndroid Build Coastguard Worker
1228*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " .off%d_1 = %d,", i + 1,
1229*7304104dSAndroid Build Coastguard Worker MAX (0, instr->operands[i].off1 - minoff[i][0]));
1230*7304104dSAndroid Build Coastguard Worker
1231*7304104dSAndroid Build Coastguard Worker if (nbitoff[i][1] != 0)
1232*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " .off%d_2 = %d,", i + 1,
1233*7304104dSAndroid Build Coastguard Worker MAX (0, instr->operands[i].off2 - minoff[i][1]));
1234*7304104dSAndroid Build Coastguard Worker
1235*7304104dSAndroid Build Coastguard Worker if (nbitoff[i][2] != 0)
1236*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " .off%d_3 = %d,", i + 1,
1237*7304104dSAndroid Build Coastguard Worker MAX (0, instr->operands[i].off3 - minoff[i][2]));
1238*7304104dSAndroid Build Coastguard Worker }
1239*7304104dSAndroid Build Coastguard Worker
1240*7304104dSAndroid Build Coastguard Worker fputs (" },\n", outfile);
1241*7304104dSAndroid Build Coastguard Worker }
1242*7304104dSAndroid Build Coastguard Worker fputs ("};\n", outfile);
1243*7304104dSAndroid Build Coastguard Worker
1244*7304104dSAndroid Build Coastguard Worker fputs ("static const uint8_t match_data[] =\n{\n", outfile);
1245*7304104dSAndroid Build Coastguard Worker size_t cnt = 0;
1246*7304104dSAndroid Build Coastguard Worker for (instr = instructions; instr != NULL; instr = instr->next, ++cnt)
1247*7304104dSAndroid Build Coastguard Worker {
1248*7304104dSAndroid Build Coastguard Worker /* First count the number of bytes. */
1249*7304104dSAndroid Build Coastguard Worker size_t totalbits = 0;
1250*7304104dSAndroid Build Coastguard Worker size_t zerobits = 0;
1251*7304104dSAndroid Build Coastguard Worker bool leading_p = true;
1252*7304104dSAndroid Build Coastguard Worker size_t leadingbits = 0;
1253*7304104dSAndroid Build Coastguard Worker struct bitvalue *b = instr->bytes;
1254*7304104dSAndroid Build Coastguard Worker while (b != NULL)
1255*7304104dSAndroid Build Coastguard Worker {
1256*7304104dSAndroid Build Coastguard Worker if (b->type == zeroone)
1257*7304104dSAndroid Build Coastguard Worker {
1258*7304104dSAndroid Build Coastguard Worker ++totalbits;
1259*7304104dSAndroid Build Coastguard Worker zerobits = 0;
1260*7304104dSAndroid Build Coastguard Worker if (leading_p)
1261*7304104dSAndroid Build Coastguard Worker ++leadingbits;
1262*7304104dSAndroid Build Coastguard Worker }
1263*7304104dSAndroid Build Coastguard Worker else
1264*7304104dSAndroid Build Coastguard Worker {
1265*7304104dSAndroid Build Coastguard Worker totalbits += b->field->bits;
1266*7304104dSAndroid Build Coastguard Worker /* We must always count the mod/rm byte. */
1267*7304104dSAndroid Build Coastguard Worker if (strncasecmp (b->field->name, "mod", 3) == 0)
1268*7304104dSAndroid Build Coastguard Worker zerobits = 0;
1269*7304104dSAndroid Build Coastguard Worker else
1270*7304104dSAndroid Build Coastguard Worker zerobits += b->field->bits;
1271*7304104dSAndroid Build Coastguard Worker leading_p = false;
1272*7304104dSAndroid Build Coastguard Worker }
1273*7304104dSAndroid Build Coastguard Worker b = b->next;
1274*7304104dSAndroid Build Coastguard Worker }
1275*7304104dSAndroid Build Coastguard Worker size_t nbytes = (totalbits - zerobits + 7) / 8;
1276*7304104dSAndroid Build Coastguard Worker assert (nbytes > 0);
1277*7304104dSAndroid Build Coastguard Worker size_t leadingbytes = leadingbits / 8;
1278*7304104dSAndroid Build Coastguard Worker
1279*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " %#zx,", nbytes | (leadingbytes << 4));
1280*7304104dSAndroid Build Coastguard Worker
1281*7304104dSAndroid Build Coastguard Worker /* Now create the mask and byte values. */
1282*7304104dSAndroid Build Coastguard Worker uint8_t byte = 0;
1283*7304104dSAndroid Build Coastguard Worker uint8_t mask = 0;
1284*7304104dSAndroid Build Coastguard Worker int nbits = 0;
1285*7304104dSAndroid Build Coastguard Worker b = instr->bytes;
1286*7304104dSAndroid Build Coastguard Worker while (b != NULL)
1287*7304104dSAndroid Build Coastguard Worker {
1288*7304104dSAndroid Build Coastguard Worker if (b->type == zeroone)
1289*7304104dSAndroid Build Coastguard Worker {
1290*7304104dSAndroid Build Coastguard Worker byte = (byte << 1) | b->value;
1291*7304104dSAndroid Build Coastguard Worker mask = (mask << 1) | 1;
1292*7304104dSAndroid Build Coastguard Worker if (++nbits == 8)
1293*7304104dSAndroid Build Coastguard Worker {
1294*7304104dSAndroid Build Coastguard Worker if (leadingbytes > 0)
1295*7304104dSAndroid Build Coastguard Worker {
1296*7304104dSAndroid Build Coastguard Worker assert (mask == 0xff);
1297*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " %#" PRIx8 ",", byte);
1298*7304104dSAndroid Build Coastguard Worker --leadingbytes;
1299*7304104dSAndroid Build Coastguard Worker }
1300*7304104dSAndroid Build Coastguard Worker else
1301*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",",
1302*7304104dSAndroid Build Coastguard Worker mask, byte);
1303*7304104dSAndroid Build Coastguard Worker byte = mask = nbits = 0;
1304*7304104dSAndroid Build Coastguard Worker if (--nbytes == 0)
1305*7304104dSAndroid Build Coastguard Worker break;
1306*7304104dSAndroid Build Coastguard Worker }
1307*7304104dSAndroid Build Coastguard Worker }
1308*7304104dSAndroid Build Coastguard Worker else
1309*7304104dSAndroid Build Coastguard Worker {
1310*7304104dSAndroid Build Coastguard Worker assert (leadingbytes == 0);
1311*7304104dSAndroid Build Coastguard Worker
1312*7304104dSAndroid Build Coastguard Worker unsigned long int remaining = b->field->bits;
1313*7304104dSAndroid Build Coastguard Worker while (nbits + remaining > 8)
1314*7304104dSAndroid Build Coastguard Worker {
1315*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",",
1316*7304104dSAndroid Build Coastguard Worker mask << (8 - nbits), byte << (8 - nbits));
1317*7304104dSAndroid Build Coastguard Worker remaining = nbits + remaining - 8;
1318*7304104dSAndroid Build Coastguard Worker byte = mask = nbits = 0;
1319*7304104dSAndroid Build Coastguard Worker if (--nbytes == 0)
1320*7304104dSAndroid Build Coastguard Worker break;
1321*7304104dSAndroid Build Coastguard Worker }
1322*7304104dSAndroid Build Coastguard Worker byte <<= remaining;
1323*7304104dSAndroid Build Coastguard Worker mask <<= remaining;
1324*7304104dSAndroid Build Coastguard Worker nbits += remaining;
1325*7304104dSAndroid Build Coastguard Worker if (nbits == 8)
1326*7304104dSAndroid Build Coastguard Worker {
1327*7304104dSAndroid Build Coastguard Worker fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",", mask, byte);
1328*7304104dSAndroid Build Coastguard Worker byte = mask = nbits = 0;
1329*7304104dSAndroid Build Coastguard Worker if (--nbytes == 0)
1330*7304104dSAndroid Build Coastguard Worker break;
1331*7304104dSAndroid Build Coastguard Worker }
1332*7304104dSAndroid Build Coastguard Worker }
1333*7304104dSAndroid Build Coastguard Worker b = b->next;
1334*7304104dSAndroid Build Coastguard Worker }
1335*7304104dSAndroid Build Coastguard Worker
1336*7304104dSAndroid Build Coastguard Worker fputc_unlocked ('\n', outfile);
1337*7304104dSAndroid Build Coastguard Worker }
1338*7304104dSAndroid Build Coastguard Worker fputs ("};\n", outfile);
1339*7304104dSAndroid Build Coastguard Worker }
1340*7304104dSAndroid Build Coastguard Worker
1341*7304104dSAndroid Build Coastguard Worker
1342*7304104dSAndroid Build Coastguard Worker #if 0
1343*7304104dSAndroid Build Coastguard Worker static size_t mnemonic_maxlen;
1344*7304104dSAndroid Build Coastguard Worker static size_t mnemonic_minlen;
1345*7304104dSAndroid Build Coastguard Worker static size_t
1346*7304104dSAndroid Build Coastguard Worker which_chars (const char *str[], size_t nstr)
1347*7304104dSAndroid Build Coastguard Worker {
1348*7304104dSAndroid Build Coastguard Worker char used_char[256];
1349*7304104dSAndroid Build Coastguard Worker memset (used_char, '\0', sizeof (used_char));
1350*7304104dSAndroid Build Coastguard Worker mnemonic_maxlen = 0;
1351*7304104dSAndroid Build Coastguard Worker mnemonic_minlen = 10000;
1352*7304104dSAndroid Build Coastguard Worker for (size_t cnt = 0; cnt < nstr; ++cnt)
1353*7304104dSAndroid Build Coastguard Worker {
1354*7304104dSAndroid Build Coastguard Worker const unsigned char *cp = (const unsigned char *) str[cnt];
1355*7304104dSAndroid Build Coastguard Worker mnemonic_maxlen = MAX (mnemonic_maxlen, strlen ((char *) cp));
1356*7304104dSAndroid Build Coastguard Worker mnemonic_minlen = MIN (mnemonic_minlen, strlen ((char *) cp));
1357*7304104dSAndroid Build Coastguard Worker do
1358*7304104dSAndroid Build Coastguard Worker used_char[*cp++] = 1;
1359*7304104dSAndroid Build Coastguard Worker while (*cp != '\0');
1360*7304104dSAndroid Build Coastguard Worker }
1361*7304104dSAndroid Build Coastguard Worker size_t nused_char = 0;
1362*7304104dSAndroid Build Coastguard Worker for (size_t cnt = 0; cnt < 256; ++cnt)
1363*7304104dSAndroid Build Coastguard Worker if (used_char[cnt] != 0)
1364*7304104dSAndroid Build Coastguard Worker ++nused_char;
1365*7304104dSAndroid Build Coastguard Worker return nused_char;
1366*7304104dSAndroid Build Coastguard Worker }
1367*7304104dSAndroid Build Coastguard Worker
1368*7304104dSAndroid Build Coastguard Worker
1369*7304104dSAndroid Build Coastguard Worker static const char **mnemonic_strs;
1370*7304104dSAndroid Build Coastguard Worker static size_t nmnemonic_strs;
1371*7304104dSAndroid Build Coastguard Worker static void
1372*7304104dSAndroid Build Coastguard Worker add_mnemonics (const void *nodep, VISIT value,
1373*7304104dSAndroid Build Coastguard Worker int level __attribute__ ((unused)))
1374*7304104dSAndroid Build Coastguard Worker {
1375*7304104dSAndroid Build Coastguard Worker if (value == leaf || value == postorder)
1376*7304104dSAndroid Build Coastguard Worker mnemonic_strs[nmnemonic_strs++] = *(const char **) nodep;
1377*7304104dSAndroid Build Coastguard Worker }
1378*7304104dSAndroid Build Coastguard Worker
1379*7304104dSAndroid Build Coastguard Worker
1380*7304104dSAndroid Build Coastguard Worker struct charfreq
1381*7304104dSAndroid Build Coastguard Worker {
1382*7304104dSAndroid Build Coastguard Worker char ch;
1383*7304104dSAndroid Build Coastguard Worker int freq;
1384*7304104dSAndroid Build Coastguard Worker };
1385*7304104dSAndroid Build Coastguard Worker static struct charfreq pfxfreq[256];
1386*7304104dSAndroid Build Coastguard Worker static struct charfreq sfxfreq[256];
1387*7304104dSAndroid Build Coastguard Worker
1388*7304104dSAndroid Build Coastguard Worker
1389*7304104dSAndroid Build Coastguard Worker static int
1390*7304104dSAndroid Build Coastguard Worker compare_freq (const void *p1, const void *p2)
1391*7304104dSAndroid Build Coastguard Worker {
1392*7304104dSAndroid Build Coastguard Worker const struct charfreq *c1 = (const struct charfreq *) p1;
1393*7304104dSAndroid Build Coastguard Worker const struct charfreq *c2 = (const struct charfreq *) p2;
1394*7304104dSAndroid Build Coastguard Worker
1395*7304104dSAndroid Build Coastguard Worker if (c1->freq > c2->freq)
1396*7304104dSAndroid Build Coastguard Worker return -1;
1397*7304104dSAndroid Build Coastguard Worker if (c1->freq < c2->freq)
1398*7304104dSAndroid Build Coastguard Worker return 1;
1399*7304104dSAndroid Build Coastguard Worker return 0;
1400*7304104dSAndroid Build Coastguard Worker }
1401*7304104dSAndroid Build Coastguard Worker
1402*7304104dSAndroid Build Coastguard Worker
1403*7304104dSAndroid Build Coastguard Worker static size_t
1404*7304104dSAndroid Build Coastguard Worker compute_pfxfreq (const char *str[], size_t nstr)
1405*7304104dSAndroid Build Coastguard Worker {
1406*7304104dSAndroid Build Coastguard Worker memset (pfxfreq, '\0', sizeof (pfxfreq));
1407*7304104dSAndroid Build Coastguard Worker
1408*7304104dSAndroid Build Coastguard Worker for (size_t i = 0; i < nstr; ++i)
1409*7304104dSAndroid Build Coastguard Worker pfxfreq[i].ch = i;
1410*7304104dSAndroid Build Coastguard Worker
1411*7304104dSAndroid Build Coastguard Worker for (size_t i = 0; i < nstr; ++i)
1412*7304104dSAndroid Build Coastguard Worker ++pfxfreq[*((const unsigned char *) str[i])].freq;
1413*7304104dSAndroid Build Coastguard Worker
1414*7304104dSAndroid Build Coastguard Worker qsort (pfxfreq, 256, sizeof (struct charfreq), compare_freq);
1415*7304104dSAndroid Build Coastguard Worker
1416*7304104dSAndroid Build Coastguard Worker size_t n = 0;
1417*7304104dSAndroid Build Coastguard Worker while (n < 256 && pfxfreq[n].freq != 0)
1418*7304104dSAndroid Build Coastguard Worker ++n;
1419*7304104dSAndroid Build Coastguard Worker return n;
1420*7304104dSAndroid Build Coastguard Worker }
1421*7304104dSAndroid Build Coastguard Worker
1422*7304104dSAndroid Build Coastguard Worker
1423*7304104dSAndroid Build Coastguard Worker struct strsnlen
1424*7304104dSAndroid Build Coastguard Worker {
1425*7304104dSAndroid Build Coastguard Worker const char *str;
1426*7304104dSAndroid Build Coastguard Worker size_t len;
1427*7304104dSAndroid Build Coastguard Worker };
1428*7304104dSAndroid Build Coastguard Worker
1429*7304104dSAndroid Build Coastguard Worker static size_t
1430*7304104dSAndroid Build Coastguard Worker compute_sfxfreq (size_t nstr, struct strsnlen *strsnlen)
1431*7304104dSAndroid Build Coastguard Worker {
1432*7304104dSAndroid Build Coastguard Worker memset (sfxfreq, '\0', sizeof (sfxfreq));
1433*7304104dSAndroid Build Coastguard Worker
1434*7304104dSAndroid Build Coastguard Worker for (size_t i = 0; i < nstr; ++i)
1435*7304104dSAndroid Build Coastguard Worker sfxfreq[i].ch = i;
1436*7304104dSAndroid Build Coastguard Worker
1437*7304104dSAndroid Build Coastguard Worker for (size_t i = 0; i < nstr; ++i)
1438*7304104dSAndroid Build Coastguard Worker ++sfxfreq[((const unsigned char *) strchrnul (strsnlen[i].str, '\0'))[-1]].freq;
1439*7304104dSAndroid Build Coastguard Worker
1440*7304104dSAndroid Build Coastguard Worker qsort (sfxfreq, 256, sizeof (struct charfreq), compare_freq);
1441*7304104dSAndroid Build Coastguard Worker
1442*7304104dSAndroid Build Coastguard Worker size_t n = 0;
1443*7304104dSAndroid Build Coastguard Worker while (n < 256 && sfxfreq[n].freq != 0)
1444*7304104dSAndroid Build Coastguard Worker ++n;
1445*7304104dSAndroid Build Coastguard Worker return n;
1446*7304104dSAndroid Build Coastguard Worker }
1447*7304104dSAndroid Build Coastguard Worker
1448*7304104dSAndroid Build Coastguard Worker
1449*7304104dSAndroid Build Coastguard Worker static void
1450*7304104dSAndroid Build Coastguard Worker create_mnemonic_table (void)
1451*7304104dSAndroid Build Coastguard Worker {
1452*7304104dSAndroid Build Coastguard Worker mnemonic_strs = xmalloc (nmnemonics * sizeof (char *));
1453*7304104dSAndroid Build Coastguard Worker
1454*7304104dSAndroid Build Coastguard Worker twalk (mnemonics, add_mnemonics);
1455*7304104dSAndroid Build Coastguard Worker
1456*7304104dSAndroid Build Coastguard Worker (void) which_chars (mnemonic_strs, nmnemonic_strs);
1457*7304104dSAndroid Build Coastguard Worker
1458*7304104dSAndroid Build Coastguard Worker size_t best_so_far = 100000000;
1459*7304104dSAndroid Build Coastguard Worker char *best_prefix = NULL;
1460*7304104dSAndroid Build Coastguard Worker char *best_suffix = NULL;
1461*7304104dSAndroid Build Coastguard Worker char *best_table = NULL;
1462*7304104dSAndroid Build Coastguard Worker size_t best_table_size = 0;
1463*7304104dSAndroid Build Coastguard Worker size_t best_table_bits = 0;
1464*7304104dSAndroid Build Coastguard Worker size_t best_prefix_bits = 0;
1465*7304104dSAndroid Build Coastguard Worker
1466*7304104dSAndroid Build Coastguard Worker /* We can precompute the prefix characters. */
1467*7304104dSAndroid Build Coastguard Worker size_t npfx_char = compute_pfxfreq (mnemonic_strs, nmnemonic_strs);
1468*7304104dSAndroid Build Coastguard Worker
1469*7304104dSAndroid Build Coastguard Worker /* Compute best size for string representation including explicit NUL. */
1470*7304104dSAndroid Build Coastguard Worker for (size_t pfxbits = 0; (1u << pfxbits) < 2 * npfx_char; ++pfxbits)
1471*7304104dSAndroid Build Coastguard Worker {
1472*7304104dSAndroid Build Coastguard Worker char prefix[1 << pfxbits];
1473*7304104dSAndroid Build Coastguard Worker size_t i;
1474*7304104dSAndroid Build Coastguard Worker for (i = 0; i < (1u << pfxbits) - 1; ++i)
1475*7304104dSAndroid Build Coastguard Worker prefix[i] = pfxfreq[i].ch;
1476*7304104dSAndroid Build Coastguard Worker prefix[i] = '\0';
1477*7304104dSAndroid Build Coastguard Worker
1478*7304104dSAndroid Build Coastguard Worker struct strsnlen strsnlen[nmnemonic_strs];
1479*7304104dSAndroid Build Coastguard Worker
1480*7304104dSAndroid Build Coastguard Worker for (i = 0; i < nmnemonic_strs; ++i)
1481*7304104dSAndroid Build Coastguard Worker {
1482*7304104dSAndroid Build Coastguard Worker if (strchr (prefix, *mnemonic_strs[i]) != NULL)
1483*7304104dSAndroid Build Coastguard Worker strsnlen[i].str = mnemonic_strs[i] + 1;
1484*7304104dSAndroid Build Coastguard Worker else
1485*7304104dSAndroid Build Coastguard Worker strsnlen[i].str = mnemonic_strs[i];
1486*7304104dSAndroid Build Coastguard Worker strsnlen[i].len = strlen (strsnlen[i].str);
1487*7304104dSAndroid Build Coastguard Worker }
1488*7304104dSAndroid Build Coastguard Worker
1489*7304104dSAndroid Build Coastguard Worker /* With the prefixes gone, try to combine strings. */
1490*7304104dSAndroid Build Coastguard Worker size_t nstrsnlen = 1;
1491*7304104dSAndroid Build Coastguard Worker for (i = 1; i < nmnemonic_strs; ++i)
1492*7304104dSAndroid Build Coastguard Worker {
1493*7304104dSAndroid Build Coastguard Worker size_t j;
1494*7304104dSAndroid Build Coastguard Worker for (j = 0; j < nstrsnlen; ++j)
1495*7304104dSAndroid Build Coastguard Worker if (strsnlen[i].len > strsnlen[j].len
1496*7304104dSAndroid Build Coastguard Worker && strcmp (strsnlen[j].str,
1497*7304104dSAndroid Build Coastguard Worker strsnlen[i].str + (strsnlen[i].len
1498*7304104dSAndroid Build Coastguard Worker - strsnlen[j].len)) == 0)
1499*7304104dSAndroid Build Coastguard Worker {
1500*7304104dSAndroid Build Coastguard Worker strsnlen[j] = strsnlen[i];
1501*7304104dSAndroid Build Coastguard Worker break;
1502*7304104dSAndroid Build Coastguard Worker }
1503*7304104dSAndroid Build Coastguard Worker else if (strsnlen[i].len < strsnlen[j].len
1504*7304104dSAndroid Build Coastguard Worker && strcmp (strsnlen[i].str,
1505*7304104dSAndroid Build Coastguard Worker strsnlen[j].str + (strsnlen[j].len
1506*7304104dSAndroid Build Coastguard Worker - strsnlen[i].len)) == 0)
1507*7304104dSAndroid Build Coastguard Worker break;
1508*7304104dSAndroid Build Coastguard Worker ;
1509*7304104dSAndroid Build Coastguard Worker if (j == nstrsnlen)
1510*7304104dSAndroid Build Coastguard Worker strsnlen[nstrsnlen++] = strsnlen[i];
1511*7304104dSAndroid Build Coastguard Worker }
1512*7304104dSAndroid Build Coastguard Worker
1513*7304104dSAndroid Build Coastguard Worker size_t nsfx_char = compute_sfxfreq (nstrsnlen, strsnlen);
1514*7304104dSAndroid Build Coastguard Worker
1515*7304104dSAndroid Build Coastguard Worker for (size_t sfxbits = 0; (1u << sfxbits) < 2 * nsfx_char; ++sfxbits)
1516*7304104dSAndroid Build Coastguard Worker {
1517*7304104dSAndroid Build Coastguard Worker char suffix[1 << sfxbits];
1518*7304104dSAndroid Build Coastguard Worker
1519*7304104dSAndroid Build Coastguard Worker for (i = 0; i < (1u << sfxbits) - 1; ++i)
1520*7304104dSAndroid Build Coastguard Worker suffix[i] = sfxfreq[i].ch;
1521*7304104dSAndroid Build Coastguard Worker suffix[i] = '\0';
1522*7304104dSAndroid Build Coastguard Worker
1523*7304104dSAndroid Build Coastguard Worker size_t newlen[nstrsnlen];
1524*7304104dSAndroid Build Coastguard Worker
1525*7304104dSAndroid Build Coastguard Worker for (i = 0; i < nstrsnlen; ++i)
1526*7304104dSAndroid Build Coastguard Worker if (strchr (suffix, strsnlen[i].str[strsnlen[i].len - 1]) != NULL)
1527*7304104dSAndroid Build Coastguard Worker newlen[i] = strsnlen[i].len - 1;
1528*7304104dSAndroid Build Coastguard Worker else
1529*7304104dSAndroid Build Coastguard Worker newlen[i] = strsnlen[i].len;
1530*7304104dSAndroid Build Coastguard Worker
1531*7304104dSAndroid Build Coastguard Worker char charused[256];
1532*7304104dSAndroid Build Coastguard Worker memset (charused, '\0', sizeof (charused));
1533*7304104dSAndroid Build Coastguard Worker size_t ncharused = 0;
1534*7304104dSAndroid Build Coastguard Worker
1535*7304104dSAndroid Build Coastguard Worker const char *tablestr[nstrsnlen];
1536*7304104dSAndroid Build Coastguard Worker size_t ntablestr = 1;
1537*7304104dSAndroid Build Coastguard Worker tablestr[0] = strsnlen[0].str;
1538*7304104dSAndroid Build Coastguard Worker size_t table = newlen[0] + 1;
1539*7304104dSAndroid Build Coastguard Worker for (i = 1; i < nstrsnlen; ++i)
1540*7304104dSAndroid Build Coastguard Worker {
1541*7304104dSAndroid Build Coastguard Worker size_t j;
1542*7304104dSAndroid Build Coastguard Worker for (j = 0; j < ntablestr; ++j)
1543*7304104dSAndroid Build Coastguard Worker if (newlen[i] > newlen[j]
1544*7304104dSAndroid Build Coastguard Worker && memcmp (tablestr[j],
1545*7304104dSAndroid Build Coastguard Worker strsnlen[i].str + (newlen[i] - newlen[j]),
1546*7304104dSAndroid Build Coastguard Worker newlen[j]) == 0)
1547*7304104dSAndroid Build Coastguard Worker {
1548*7304104dSAndroid Build Coastguard Worker table += newlen[i] - newlen[j];
1549*7304104dSAndroid Build Coastguard Worker tablestr[j] = strsnlen[i].str;
1550*7304104dSAndroid Build Coastguard Worker newlen[j] = newlen[i];
1551*7304104dSAndroid Build Coastguard Worker break;
1552*7304104dSAndroid Build Coastguard Worker }
1553*7304104dSAndroid Build Coastguard Worker else if (newlen[i] < newlen[j]
1554*7304104dSAndroid Build Coastguard Worker && memcmp (strsnlen[i].str,
1555*7304104dSAndroid Build Coastguard Worker tablestr[j] + (newlen[j] - newlen[i]),
1556*7304104dSAndroid Build Coastguard Worker newlen[i]) == 0)
1557*7304104dSAndroid Build Coastguard Worker break;
1558*7304104dSAndroid Build Coastguard Worker
1559*7304104dSAndroid Build Coastguard Worker if (j == ntablestr)
1560*7304104dSAndroid Build Coastguard Worker {
1561*7304104dSAndroid Build Coastguard Worker table += newlen[i] + 1;
1562*7304104dSAndroid Build Coastguard Worker tablestr[ntablestr] = strsnlen[i].str;
1563*7304104dSAndroid Build Coastguard Worker newlen[ntablestr] = newlen[i];
1564*7304104dSAndroid Build Coastguard Worker
1565*7304104dSAndroid Build Coastguard Worker ++ntablestr;
1566*7304104dSAndroid Build Coastguard Worker }
1567*7304104dSAndroid Build Coastguard Worker
1568*7304104dSAndroid Build Coastguard Worker for (size_t x = 0; x < newlen[j]; ++x)
1569*7304104dSAndroid Build Coastguard Worker if (charused[((const unsigned char *) tablestr[j])[x]]++ == 0)
1570*7304104dSAndroid Build Coastguard Worker ++ncharused;
1571*7304104dSAndroid Build Coastguard Worker }
1572*7304104dSAndroid Build Coastguard Worker
1573*7304104dSAndroid Build Coastguard Worker size_t ncharused_bits = 0;
1574*7304104dSAndroid Build Coastguard Worker i = 1;
1575*7304104dSAndroid Build Coastguard Worker while (i < ncharused)
1576*7304104dSAndroid Build Coastguard Worker {
1577*7304104dSAndroid Build Coastguard Worker i *= 2;
1578*7304104dSAndroid Build Coastguard Worker ++ncharused_bits;
1579*7304104dSAndroid Build Coastguard Worker }
1580*7304104dSAndroid Build Coastguard Worker
1581*7304104dSAndroid Build Coastguard Worker size_t table_bits = 0;
1582*7304104dSAndroid Build Coastguard Worker i = 1;
1583*7304104dSAndroid Build Coastguard Worker while (i < table)
1584*7304104dSAndroid Build Coastguard Worker {
1585*7304104dSAndroid Build Coastguard Worker i *= 2;
1586*7304104dSAndroid Build Coastguard Worker ++table_bits;
1587*7304104dSAndroid Build Coastguard Worker }
1588*7304104dSAndroid Build Coastguard Worker
1589*7304104dSAndroid Build Coastguard Worker size_t mnemonic_bits = table_bits + pfxbits + sfxbits;
1590*7304104dSAndroid Build Coastguard Worker size_t new_total = (((table + 7) / 8) * ncharused_bits + ncharused
1591*7304104dSAndroid Build Coastguard Worker + (pfxbits == 0 ? 0 : (1 << pfxbits) - 1)
1592*7304104dSAndroid Build Coastguard Worker + (sfxbits == 0 ? 0 : (1 << sfxbits) - 1)
1593*7304104dSAndroid Build Coastguard Worker + (((total_bits + mnemonic_bits + 7) / 8)
1594*7304104dSAndroid Build Coastguard Worker * ninstructions));
1595*7304104dSAndroid Build Coastguard Worker
1596*7304104dSAndroid Build Coastguard Worker if (new_total < best_so_far)
1597*7304104dSAndroid Build Coastguard Worker {
1598*7304104dSAndroid Build Coastguard Worker best_so_far = new_total;
1599*7304104dSAndroid Build Coastguard Worker best_mnemonic_bits = mnemonic_bits;
1600*7304104dSAndroid Build Coastguard Worker
1601*7304104dSAndroid Build Coastguard Worker free (best_suffix);
1602*7304104dSAndroid Build Coastguard Worker best_suffix = xstrdup (suffix);
1603*7304104dSAndroid Build Coastguard Worker
1604*7304104dSAndroid Build Coastguard Worker free (best_prefix);
1605*7304104dSAndroid Build Coastguard Worker best_prefix = xstrdup (prefix);
1606*7304104dSAndroid Build Coastguard Worker best_prefix_bits = pfxbits;
1607*7304104dSAndroid Build Coastguard Worker
1608*7304104dSAndroid Build Coastguard Worker best_table_size = table;
1609*7304104dSAndroid Build Coastguard Worker best_table_bits = table_bits;
1610*7304104dSAndroid Build Coastguard Worker char *cp = best_table = xrealloc (best_table, table);
1611*7304104dSAndroid Build Coastguard Worker for (i = 0; i < ntablestr; ++i)
1612*7304104dSAndroid Build Coastguard Worker {
1613*7304104dSAndroid Build Coastguard Worker assert (cp + newlen[i] + 1 <= best_table + table);
1614*7304104dSAndroid Build Coastguard Worker cp = mempcpy (cp, tablestr[i], newlen[i]);
1615*7304104dSAndroid Build Coastguard Worker *cp++ = '\0';
1616*7304104dSAndroid Build Coastguard Worker }
1617*7304104dSAndroid Build Coastguard Worker assert (cp == best_table + table);
1618*7304104dSAndroid Build Coastguard Worker }
1619*7304104dSAndroid Build Coastguard Worker }
1620*7304104dSAndroid Build Coastguard Worker }
1621*7304104dSAndroid Build Coastguard Worker
1622*7304104dSAndroid Build Coastguard Worker fputs ("static const char mnemonic_table[] =\n\"", outfile);
1623*7304104dSAndroid Build Coastguard Worker for (size_t i = 0; i < best_table_size; ++i)
1624*7304104dSAndroid Build Coastguard Worker {
1625*7304104dSAndroid Build Coastguard Worker if (((i + 1) % 60) == 0)
1626*7304104dSAndroid Build Coastguard Worker fputs ("\"\n\"", outfile);
1627*7304104dSAndroid Build Coastguard Worker if (!isascii (best_table[i]) || !isprint (best_table[i]))
1628*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "\\%03o", best_table[i]);
1629*7304104dSAndroid Build Coastguard Worker else
1630*7304104dSAndroid Build Coastguard Worker fputc (best_table[i], outfile);
1631*7304104dSAndroid Build Coastguard Worker }
1632*7304104dSAndroid Build Coastguard Worker fputs ("\";\n", outfile);
1633*7304104dSAndroid Build Coastguard Worker
1634*7304104dSAndroid Build Coastguard Worker if (best_prefix[0] != '\0')
1635*7304104dSAndroid Build Coastguard Worker fprintf (outfile,
1636*7304104dSAndroid Build Coastguard Worker "static const char prefix[%zu] = \"%s\";\n"
1637*7304104dSAndroid Build Coastguard Worker "#define PREFIXCHAR_BITS %zu\n",
1638*7304104dSAndroid Build Coastguard Worker strlen (best_prefix), best_prefix, best_prefix_bits);
1639*7304104dSAndroid Build Coastguard Worker else
1640*7304104dSAndroid Build Coastguard Worker fputs ("#define NO_PREFIX\n", outfile);
1641*7304104dSAndroid Build Coastguard Worker
1642*7304104dSAndroid Build Coastguard Worker if (best_suffix[0] != '\0')
1643*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "static const char suffix[%zu] = \"%s\";\n",
1644*7304104dSAndroid Build Coastguard Worker strlen (best_suffix), best_suffix);
1645*7304104dSAndroid Build Coastguard Worker else
1646*7304104dSAndroid Build Coastguard Worker fputs ("#define NO_SUFFIX\n", outfile);
1647*7304104dSAndroid Build Coastguard Worker
1648*7304104dSAndroid Build Coastguard Worker for (size_t i = 0; i < nmnemonic_strs; ++i)
1649*7304104dSAndroid Build Coastguard Worker {
1650*7304104dSAndroid Build Coastguard Worker const char *mne = mnemonic_strs[i];
1651*7304104dSAndroid Build Coastguard Worker
1652*7304104dSAndroid Build Coastguard Worker size_t pfxval = 0;
1653*7304104dSAndroid Build Coastguard Worker char *cp = strchr (best_prefix, *mne);
1654*7304104dSAndroid Build Coastguard Worker if (cp != NULL)
1655*7304104dSAndroid Build Coastguard Worker {
1656*7304104dSAndroid Build Coastguard Worker pfxval = 1 + (cp - best_prefix);
1657*7304104dSAndroid Build Coastguard Worker ++mne;
1658*7304104dSAndroid Build Coastguard Worker }
1659*7304104dSAndroid Build Coastguard Worker
1660*7304104dSAndroid Build Coastguard Worker size_t l = strlen (mne);
1661*7304104dSAndroid Build Coastguard Worker
1662*7304104dSAndroid Build Coastguard Worker size_t sfxval = 0;
1663*7304104dSAndroid Build Coastguard Worker cp = strchr (best_suffix, mne[l - 1]);
1664*7304104dSAndroid Build Coastguard Worker if (cp != NULL)
1665*7304104dSAndroid Build Coastguard Worker {
1666*7304104dSAndroid Build Coastguard Worker sfxval = 1 + (cp - best_suffix);
1667*7304104dSAndroid Build Coastguard Worker --l;
1668*7304104dSAndroid Build Coastguard Worker }
1669*7304104dSAndroid Build Coastguard Worker
1670*7304104dSAndroid Build Coastguard Worker char *off = memmem (best_table, best_table_size, mne, l);
1671*7304104dSAndroid Build Coastguard Worker while (off[l] != '\0')
1672*7304104dSAndroid Build Coastguard Worker {
1673*7304104dSAndroid Build Coastguard Worker off = memmem (off + 1, best_table_size, mne, l);
1674*7304104dSAndroid Build Coastguard Worker assert (off != NULL);
1675*7304104dSAndroid Build Coastguard Worker }
1676*7304104dSAndroid Build Coastguard Worker
1677*7304104dSAndroid Build Coastguard Worker fprintf (outfile, "#define MNE_%s %#zx\n",
1678*7304104dSAndroid Build Coastguard Worker mnemonic_strs[i],
1679*7304104dSAndroid Build Coastguard Worker (off - best_table)
1680*7304104dSAndroid Build Coastguard Worker + ((pfxval + (sfxval << best_prefix_bits)) << best_table_bits));
1681*7304104dSAndroid Build Coastguard Worker }
1682*7304104dSAndroid Build Coastguard Worker }
1683*7304104dSAndroid Build Coastguard Worker #endif
1684