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