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