22
#define MAX_OL_TYPES 82
25
#define MAX_ASM_TAB 2048
27
#define MAX_SAVED_MNEMS 10
28
#define MAX_SLASH_ENTRIES 20
29
#define MAX_HASH_ENTRIES 15
30
#define MAX_STAR_ENTRIES 15
31
#define MAX_LOCKTAB_ENTRIES 50
32
#define MAX_AGROUP_ENTRIES 14
40
#define NUMBER(x) (sizeof(x) / sizeof(*x))
42
#define AsmTbl "asmtbl"
43
#define DisTbl "distbl"
45
static char line[LINELEN];
46
static const char *filename;
56
static int n_ol_types = 0;
57
static struct keytab olkeydict[MAX_OL_TYPES];
58
static char *olnames[MAX_OL_TYPES];
59
static int oloffset[MAX_OL_TYPES];
62
static struct keytab *keyord1[MAX_N_ORDS];
63
static struct keytab *keyord2[MAX_N_ORDS];
64
static Boolean ordsmall[MAX_OL_TYPES];
81
#define ASM_LOCKREP 0xf5
82
#define ASM_LOCKABLE 0xf4
86
static int n_asm_tab = 0;
87
static unsigned char asmtab[MAX_ASM_TAB];
98
static struct mnrec mnlist[MAX_MNRECS];
99
static struct mnrec *mnhead;
101
static int n_saved_mnems = 0;
102
static int saved_mnem[MAX_SAVED_MNEMS];
104
static int n_slash_entries;
105
static int slashtab_seq[MAX_SLASH_ENTRIES];
106
static int slashtab_mn[MAX_SLASH_ENTRIES];
108
static int n_hash_entries;
109
static int hashtab_seq[MAX_HASH_ENTRIES];
110
static int hashtab_mn[MAX_HASH_ENTRIES];
112
static int n_star_entries;
113
static int startab_seq[MAX_STAR_ENTRIES];
114
static int startab_mn[MAX_STAR_ENTRIES];
117
static int locktab[MAX_LOCKTAB_ENTRIES];
120
static int agroup_i[MAX_AGROUP_ENTRIES];
121
static int agroup_inf[MAX_AGROUP_ENTRIES];
129
static unsigned int fpgrouptab[] = {0xd9e8, 0xd9f0, 0xd9f8};
133
#define GROUP(i) (256 + 8 * ((i) - 1))
134
#define COPR(i) (256 + 8 * NGROUPS + 16 * (i))
135
#define FPGROUP(i) (256 + 8 * NGROUPS + 16 * 8 + 8 * (i))
136
#define SPARSE_BASE (256 + 8 * NGROUPS + 16 * 8 + 8 * NUMBER(fpgrouptab))
161
static unsigned int sp_fpgrouptab[] = {
162
0xd9d0, 0xd9e0, 0xdae8, 0xdbe0, 0xded8, 0xdfe0 };
166
#define SGROUP(i) (SPARSE_BASE + 256 + 8 * ((i) - 1))
167
#define SFPGROUP(i) (SPARSE_BASE + 256 + 8 * NSGROUPS + 8 * (i))
168
#define NOPS (SPARSE_BASE + 256 + 8 * NSGROUPS + 8 * NUMBER(sp_fpgrouptab))
170
static int optype[NOPS];
171
static int opinfo[NOPS];
172
static unsigned char opmach[NOPS];
194
{ SPARSE_BASE + 0x00, GROUP(8) },
195
{ SPARSE_BASE + 0x01, GROUP(9) }
205
{ SPARSE_BASE+0xba, SGROUP(2) },
206
{ SPARSE_BASE+0xc7, SGROUP(3) },
216
static struct inforec {
220
{ 0, "main opcode part" },
221
{ GROUP(1), "Intel group 1" },
222
{ GROUP(3), "Intel group 2" },
223
{ GROUP(5), "Intel group 2a" },
224
{ GROUP(6), "Intel group 3" },
225
{ GROUP(7), "Intel group 5" },
226
{ GROUP(8), "Intel group 6" },
227
{ GROUP(9), "Intel group 7" },
228
{ COPR(0), "Coprocessor d8" },
229
{ COPR(1), "Coprocessor d9" },
230
{ COPR(2), "Coprocessor da" },
231
{ COPR(3), "Coprocessor db" },
232
{ COPR(4), "Coprocessor dc" },
233
{ COPR(5), "Coprocessor dd" },
234
{ COPR(6), "Coprocessor de" },
235
{ COPR(7), "Coprocessor df" },
236
{ FPGROUP(0), "Coprocessor groups" },
240
static char *spectab[] = { "WAIT", "ORG", "DD", "DW", "DB" };
241
static char *spectab2[] = { "LOCKREP", "SEG" };
247
static volatile void fail( const char *message, ... )
252
va_start( args, message );
253
vfprintf( stderr, message, args );
255
putc( '\n', stderr );
259
static FILE * openread( const char *path )
264
f = fopen( path, "r" );
274
static volatile void linenofail( const char *message, ... )
279
fprintf( stderr, "Line %d of `%s': ", lineno, filename );
280
va_start( args, message );
281
vfprintf( stderr, message, args );
283
putc( '\n', stderr );
287
static void * xmalloc( unsigned int len, const char *why )
290
void *ptr = malloc( len );
292
if ( ptr == NULL ) fail( "Cannot allocate %u bytes for %s", len, why );
300
static Boolean getline( FILE *ff )
306
if ( fgets( line, LINELEN, ff ) == NULL ) return False;
308
if ( line[0] == '#' ) continue;
309
n = strlen( line ) - 1;
310
if ( n < 0 || line[n] != '\n' )
311
linenofail( "too long." );
312
if ( n > 0 && line[n-1] == '\r' ) --n;
313
if ( n == 0 ) continue;
319
static short getkey( char **pp )
325
if (*p == ' ' || *p == '\t' || *p == ';' || *p == '\0')
326
linenofail("key expected");
328
if (*p != ' ' && *p != '\t' && *p != ';' && *p != '\0') {
329
key = (key << 8) | *p++;
330
if (*p != ' ' && *p != '\t' && *p != ';' && *p != '\0')
331
linenofail("key too long");
342
static void marksmall( struct keytab *kp )
347
ordsmall[kp - olkeydict] = True;
348
for ( i = 0; i < n_ords; ++i )
349
if ( keyord2[i] == kp )
350
marksmall( keyord1[i] );
359
static void add_to_asmtab( unsigned char byte )
362
if ( n_asm_tab >= MAX_ASM_TAB )
363
linenofail( "Assembler table overflow." );
364
asmtab[n_asm_tab++] = byte;
368
static unsigned char getmachine( char **pp )
374
if ( *p != ';' ) return 0;
376
if ( *p < '0' || *p > '6' )
377
linenofail( "bad machine type" );
379
add_to_asmtab( (unsigned char)(ASM_MACH0 + value) );
384
static struct keytab * lookupkey( short key )
389
for ( kp = olkeydict; kp < olkeydict + NUMBER(olkeydict); ++kp )
390
if ( key == kp->key )
392
linenofail( "can't find key %X", key );
396
static char * skipwhite( char *p )
399
while ( *p == ' ' || *p == '\t' ) ++p;
407
static void entertable( int i, int type, int info )
410
if ( optype[i] != 0 )
411
linenofail( "Duplicate information for index %d", i );
420
static int getnybble( char c )
423
if ( c >= '0' && c <= '9' ) return c - '0';
424
if ( c >= 'a' && c <= 'f' ) return c - 'a' + 10;
425
linenofail( "Hex digit expected instead of `%c'", c );
433
static int getbyte( char **pp )
439
answer = getnybble( *p++ );
440
answer = (answer << 4) | getnybble( *p++ );
450
static int getslash( char **pp )
456
if ( *p != '/' ) linenofail( "`/' expected" );
458
if ( *p < '0' || *p > '7' ) linenofail( "Octal digit expected" );
469
static int entermn(char *str, char *str_end)
474
if ( num_mnrecs >= MAX_MNRECS )
475
linenofail( "Too many mnemonics" );
478
if ( n_saved_mnems >= MAX_SAVED_MNEMS )
479
linenofail( "Too many mnemonics to save" );
480
saved_mnem[n_saved_mnems++] = num_mnrecs;
484
p = xmalloc( str_end - str + 1, "mnemonic name" );
485
mnlist[num_mnrecs].string = p;
486
mnlist[num_mnrecs].len = str_end - str;
488
while ( str < str_end ) *p++ = toupper( *str++ );
491
memcpy( p, str, str_end - str );
492
*(p+(str_end - str)) = 0;
495
mnlist[num_mnrecs].asmoffset = n_asm_tab;
503
static struct mnrec * mn_sort(struct mnrec *start, int len)
506
struct mnrec *p1, *p2, *answer;
507
struct mnrec **headpp;
514
p1 = mn_sort(start, i);
515
p2 = mn_sort(start + i, len - i);
518
if ( strcmp(p1->string, p2->string) < 0 ) {
544
static void read_is( FILE *f1 )
549
entertable( 0x0f, OPTWOBYTE, SPARSE_BASE );
550
entertable( 0x26, OPPREFIX, PRESEG | (0 << 8) );
551
entertable( 0x2e, OPPREFIX, PRESEG | (1 << 8) );
552
entertable( 0x36, OPPREFIX, PRESEG | (2 << 8) );
553
entertable( 0x3e, OPPREFIX, PRESEG | (3 << 8) );
554
entertable( 0x64, OPPREFIX, PRESEG | (4 << 8) );
555
entertable( 0x65, OPPREFIX, PRESEG | (5 << 8) );
556
entertable( 0xf2, OPPREFIX, PREREP );
557
entertable( 0xf3, OPPREFIX, PREREP | PREREPZ );
558
entertable( 0xf0, OPPREFIX, PRELOCK );
559
entertable( 0x66, OPPREFIX, PRE32D );
560
entertable( 0x67, OPPREFIX, PRE32A );
561
opmach[0x64] = opmach[0x65] = opmach[0x66] = opmach[0x67] = 3;
563
for ( i = 0; i < NUMBER(grouptab); ++i )
564
entertable(grouptab[i].seq, OPGROUP, grouptab[i].info);
565
for ( i = 0; i < NUMBER(sp_grouptab); ++i )
566
entertable(sp_grouptab[i].seq, OPGROUP, sp_grouptab[i].info);
567
for ( i = 0; i < 8; ++i )
568
entertable(0xd8 + i, OPCOPR, COPR(i));
569
for ( i = 0; i < NUMBER(fpgrouptab); ++i ) {
570
unsigned int j = fpgrouptab[i];
571
unsigned int k = (j >> 8) - 0xd8;
573
if ( k > 8 || (j & 0xff) < 0xc0 )
574
fail( "Bad value for fpgrouptab[%d]", i );
575
entertable( COPR(k) + 8 + (((j & 0xff) - 0xc0) >> 3 ),
576
OPFPGROUP, FPGROUP(i));
578
for ( i = 0; i < NUMBER(sp_fpgrouptab); ++i ) {
579
unsigned int j = sp_fpgrouptab[i];
580
unsigned int k = (j >> 8) - 0xd8;
582
if ( k > 8 || ( j & 0xff ) < 0xc0 )
583
fail( "Bad value for sp_fpgrouptab[%d]", i );
584
entertable( COPR(k) + 8 + (((j & 0xff) - 0xc0) >> 3 ),
585
OPFPGROUP, SFPGROUP(i));
590
while ( getline( f1 ) ) {
593
char *p, *p0, *pslash, *phash, *pstar;
594
Boolean asm_only_line;
595
unsigned char atab_addendum;
597
asm_only_line = False;
599
if ( line[0] == '_' ) {
600
asm_only_line = True;
603
atab_addendum = '\0';
605
static const unsigned char uptab[] =
606
{ASM_AAX, ASM_DB, ASM_DW,
607
ASM_DD, ASM_ORG, ASM_D32};
610
atab_addendum = uptab[*p0++ - '0'];
612
p = strchr( p0, ' ' );
613
if ( p == NULL ) p = p0 + strlen( p0 );
617
pslash = memchr( p0, '/', p - p0 );
618
phash = memchr( p0, '#', p - p0 );
619
pstar = memchr( p0, '*', p - p0 );
620
if ( pslash != NULL ) {
621
mnem = entermn( p0, pslash );
622
add_to_asmtab( (unsigned char)ASM_D16 );
625
mn_alt = entermn( pslash, p );
626
add_to_asmtab( (unsigned char)ASM_D32 );
627
} else if ( phash != NULL ) {
628
mnem = entermn( p0, phash );
629
add_to_asmtab( (unsigned char)ASM_D16 );
632
mn_alt = entermn( phash, p );
633
add_to_asmtab( (unsigned char)ASM_D32 );
634
} else if ( pstar != NULL ) {
635
mn_alt = entermn( p0, pstar );
636
add_to_asmtab( (unsigned char)ASM_WAIT );
638
mnem = entermn( pstar, p );
640
mnem = entermn( p0, p );
643
if ( atab_addendum != '\0' ) add_to_asmtab( atab_addendum );
645
atab_addendum = ASM_END;
646
memset( ordsmall, 0, n_keys * sizeof(Boolean) );
650
while ( *p == ' ' ) {
654
unsigned char machine;
655
unsigned long atab_inf;
656
unsigned short atab_key;
657
unsigned char atab_xtra = 0;
659
while ( *p == ' ' ) ++p;
660
asm_only = asm_only_line;
666
else if ( *p == 'D' ) {
674
if ( dis_only == False )
675
add_to_asmtab( (unsigned char)ASM_LOCKABLE );
677
atab_inf = i = getbyte( &p );
683
if ( optype[i] == OPGROUP ) {
684
int j = getslash( &p );
687
for ( k = 0;; ++k ) {
688
if ( k >= n_agroups ) {
689
if ( ++n_agroups > MAX_AGROUP_ENTRIES )
690
linenofail( "Too many agroup entries" );
692
agroup_inf[k] = atab_inf;
695
if ( agroup_i[k] == i )
698
atab_inf = 0x240 + 8 * k + j;
701
if ( optype[i] == OPCOPR ) {
703
int j = getslash( &p );
705
atab_inf = 0x200 + j * 8 + (i - 0xd8);
708
atab_xtra = getbyte( &p );
709
if ( atab_xtra < 0xc0 )
710
linenofail( "Bad second escape byte" );
711
i = opinfo[i] + 8 + ((atab_xtra - 0xc0) >> 3);
712
if ( optype[i] == OPFPGROUP )
713
i = opinfo[i] + (atab_xtra & 7);
718
machine = getmachine( &p );
720
entertable( i, OPSIMPLE, mnem );
727
add_to_asmtab( (unsigned char)ASM_LOCKREP );
728
add_to_asmtab( (unsigned char)atab_inf );
729
atab_addendum = '\0';
732
add_to_asmtab( (unsigned char)ASM_SEG );
733
add_to_asmtab( (unsigned char)atab_inf );
734
atab_addendum = '\0';
737
struct keytab *kp = lookupkey(getkey(&p));
738
int width = kp->width;
741
machine = getmachine(&p);
745
if ( ordsmall[kp - olkeydict] )
746
linenofail( "Variants out of order." );
749
atab_key = kp->value + 1;
750
if ( ( i >= 256 && i < SPARSE_BASE )
751
|| i >= SPARSE_BASE + 256 ) {
753
linenofail( "width failure" );
756
if ( i & ( width - 1 ) )
757
linenofail( "width alignment failure" );
759
for ( j = ( i == 0x90 ); j < width; ++j ) {
761
entertable(i|j, oloffset[kp->value], mnem);
762
opmach[i | j] = machine;
764
if ( n_locktab >= MAX_LOCKTAB_ENTRIES )
765
linenofail("Too many lockable "
767
locktab[n_locktab] = i | j;
774
linenofail("Syntax error.");
776
if ( atab_addendum != '\0' && dis_only == False ) {
777
atab_inf = atab_inf * (unsigned short) (n_ol_types + 1)
779
add_to_asmtab( (unsigned char)(atab_inf >> 8) );
780
if ( ( atab_inf >> 8 ) >= ASM_MACH0 )
781
fail( "Assembler table is too busy" );
782
add_to_asmtab( (unsigned char)atab_inf );
783
if ( atab_xtra != 0 )
784
add_to_asmtab( atab_xtra );
786
if ( pslash != NULL ) {
787
if ( n_slash_entries >= MAX_SLASH_ENTRIES )
788
linenofail( "Too many slash entries" );
789
slashtab_seq[n_slash_entries] = i;
790
slashtab_mn[n_slash_entries] = mn_alt;
792
} else if ( phash != NULL ) {
793
if ( n_hash_entries >= MAX_HASH_ENTRIES )
794
linenofail( "Too many hash entries" );
795
hashtab_seq[n_hash_entries] = i;
796
hashtab_mn[n_hash_entries] = mn_alt;
798
} else if ( pstar != NULL ) {
799
if ( n_star_entries >= MAX_STAR_ENTRIES )
800
linenofail( "Too many star entries" );
801
startab_seq[n_star_entries] = i;
802
startab_mn[n_star_entries] = mn_alt;
807
linenofail( "Syntax error." );
808
if ( atab_addendum != '\0' ) {
809
add_to_asmtab( atab_addendum );
816
static void put_dw( FILE *f2, const char *label, int *datap, int n )
825
for (i = (n <= 8 ? n : 8); i > 0; --i) {
828
fprintf( f2, "0%xh", *datap++);
839
static void dumptablesAsm(FILE *f2)
846
struct inforec *tblptr;
853
if ( num_mnrecs == 0 )
854
fail( "No assembler mnemonics!" );
858
mnhead = mn_sort(mnlist, num_mnrecs);
861
for ( i = 0; i < num_mnrecs; i++ )
862
mnlist[i].next = &mnlist[i+1];
863
mnlist[num_mnrecs-1].next = NULL;
866
fprintf( f2, "\n;--- This file was generated by mktables.exe.\n" );
870
fputs( "\n;--- Operand type lists.\n"
871
";--- They were read from file INSTR.KEY.\n\n"
872
";--- They are referenced thru table opindex.\n\n"
873
"oplists label byte\n\topl 00\t;void - for instructions without operands\n", f2 );
874
for ( i = 0; i < n_ol_types; ++i ) {
876
unsigned char szKey[4];
877
if ( olkeydict[i].key > 0xFF ) {
878
szKey[0] = (unsigned char)(olkeydict[i].key >> 8);
879
szKey[1] = (unsigned char)(olkeydict[i].key & 0xFF);
882
szKey[0] = (unsigned char)(olkeydict[i].key);
885
fprintf( f2, "\topl %s, %s\t; ofs=%Xh\n", szKey, olnames[i], oloffset[i] );
887
fprintf( f2, "\topl %02X,%s\t; idx=%u, ofs=%Xh\n", i+1, olnames[i], i+1, oloffset[i] );
891
fprintf( f2, "\nASMMOD\tEQU %0Xh\n", n_ol_types+1 );
896
fputs( "\n;--- Assembler: data on groups.\n"
897
";--- If HiByte == 01, it's a \"0F-prefix\" group.\n\n"
898
"agroups label word\n", f2);
899
for ( i = 0; i < n_agroups; ++i ) {
900
fprintf( f2, "\tdw %03Xh\t;%u\n", agroup_inf[i], i );
905
fputs( "\n;--- List of assembler mnemonics and data.\n"
906
";--- variant's 1. argument (=a):\n"
907
";--- if a < 0x100: one byte opcode.\n"
908
";--- if a >= 0x100 && a < 0x200: two byte \"0F\"-opcode.\n"
909
";--- if a >= 0x200 && a < 0x240: fp instruction.\n"
910
";--- if a >= 0x240: refers to agroups [macro AGRP() is used].\n"
911
";--- variant's 2. argument is index for array opindex.\n\n"
912
"mnlist label byte\n", f2 );
913
for ( mnp = mnhead, offset = 0; mnp != NULL; mnp = mnp->next ) {
914
mnp->offset = offset + 2;
915
offset += mnp->len + 2;
916
fprintf( f2, "\tmne %s", mnp->string );
920
if ( asmtab[i] == ASM_D16 && asmtab[i+1] == ASM_D32 ) {
922
fprintf( f2, ", ASM_D16\t; ofs=%Xh\n", i );
923
} else if ( asmtab[i] >= ASM_WAIT ) {
924
fprintf( f2, ", ASM_%s\t; ofs=%Xh\n", spectab[asmtab[i] - ASM_WAIT], i );
925
} else if ( ( asmtab[i] == ASM_SEG || asmtab[i] == ASM_LOCKREP ) ) {
926
fprintf( f2, ", ASM_%s, %03xh\t; ofs=%Xh\n", spectab2[asmtab[i] - ASM_LOCKREP], asmtab[i+1], i );
929
while ( asmtab[j] > ASM_SEG && asmtab[j] < ASM_WAIT ) {
930
switch ( asmtab[j] ) {
932
fprintf( f2, ", ASM_AAX" );
935
fprintf( f2, ", ASM_D16" );
938
fprintf( f2, ", ASM_D32" );
943
fprintf( f2, "\t; ofs=%Xh\n", i );
945
for ( ; j < n_asm_tab; ) {
947
char machstr[12] = {""};
948
if ( asmtab[j] == 0xFF )
951
if ( asmtab[j] == ASM_LOCKABLE ) {
952
lockstr = "ASM_LOCKABLE";
956
if ( asmtab[j] == 0xFF )
958
if ( asmtab[j] >= ASM_MACH0 && asmtab[j] <= ASM_MACH6 ) {
959
sprintf( machstr, "ASM_MACH%u", asmtab[j] - ASM_MACH0 );
963
k = (int)asmtab[j] * 256 + asmtab[j+1];
964
l = k % (n_ol_types+1);
965
k = k / (n_ol_types+1);
967
if ( k >= 0xD8 && k <= 0xDF )
968
fprintf( f2, "\t fpvariant " );
970
fprintf( f2, "\t variant " );
973
fprintf( f2, "AGRP(%u,%u), %u", (k - 0x240) >> 3, (k - 0x240) & 7, l );
975
fprintf( f2, "%03xh, %u", k, l );
978
if ( k >= 0xD8 && k <= 0xDF) {
979
fprintf( f2, ", %03xh", asmtab[j] );
982
if ( *lockstr == '\0' && machstr[0] == '\0' )
984
else if ( machstr[0] == '\0' )
985
fprintf( f2, ", %s\n", lockstr );
987
fprintf( f2, ", %s, %s\n", lockstr, machstr );
989
fprintf( f2, "\t endvariant\n");
994
fputs( "\nend_mnlist label byte\n\n", f2);
996
if (offset >= (1 << MSHIFT)) {
997
fprintf(stderr, "%d bytes of mnemonics. That's too many.\n", offset);
1007
static void dumptablesDis(FILE *f2)
1012
struct inforec *tblptr;
1019
fprintf( f2, "\n;--- This file was generated by mktables.exe.\n\n" );
1023
fputs( ";--- compressed table of the opcode types."
1024
"\n;--- If the item has the format OT(xx), it refers to table 'oplists'."
1025
"\n;--- Otherwise it's an offset for internal table 'dis_jmp2'."
1026
"\n\nOTDATA segment"
1027
"\n\noptypes label byte", f2);
1029
tblptr = tblcomments;
1031
for ( i = 0; i < SPARSE_BASE; i += 8 ) {
1032
for ( j = 0; j < 8; ++j ) {
1033
fputs( auxstr, f2 );
1034
if ( optype[i + j] >= OPTYPES ) {
1036
if ( optype[i + j] > OPTYPES )
1037
for ( y = 1; y <= n_ol_types; y++ )
1038
if ( oloffset[y-1] == optype[i + j] )
1040
if ( y <= n_ol_types )
1041
fprintf( f2, "OT(%02X)", y );
1043
fail("offset not found for %u: %X", i+j, optype[i+j] );
1045
fprintf( f2, " %03Xh", optype[i + j] );
1048
fprintf( f2, "\t; %02x - %02x", i, i + 7 );
1049
if ( i == tblptr->seqno ) {
1050
fprintf( f2, " (%s)", (tblptr++)->string );
1055
fprintf( f2, "\nSPARSE_BASE\tequ $ - optypes\n" );
1057
auxstr = "\n;--- The rest of these are squeezed.\n" "\tdb 0,";
1058
for ( i = SPARSE_BASE, k=1; i < NOPS; ++i )
1059
if ( ( j = optype[i] ) != 0 ) {
1061
if ( j >= OPTYPES ) {
1064
for ( y = 1; y <= n_ol_types; y++ )
1065
if ( oloffset[y-1] == j )
1067
if ( y <= n_ol_types)
1068
fprintf( f2, "%sOT(%02X)", auxstr, y );
1070
fail("offset not found for %u: %X", i, j );
1072
fprintf( f2, "%s %03Xh", auxstr, j );
1074
if ( (k & 7) == 0 ) {
1075
fprintf( f2, "\t;%02X", k-8 );
1080
fputs( "\n\nOTDATA ends\n", f2 );
1085
for ( i = 1; i < 7; i++ )
1086
fprintf( f2, "P%u86\tequ %Xh\n", i, i << MSHIFT );
1088
fputs( "\n\talign 2\n", f2 );
1090
fputs( "\n;--- compressed table of additional information."
1091
"\n;--- Bits 0-11 are the offset of the mnemonics table if"
1092
"\n;--- the corresponding item in optypes is defined via OT();"
1093
"\n;--- else it's a parameter for the optype processing."
1094
"\n;--- Bits 12-15 are the cpu which introduced this opcode."
1095
"\n\nopinfo label word\n", f2 );
1097
for ( i = 0; i < SPARSE_BASE; i += 4 ) {
1099
for ( j = 0; j < 4; ++j ) {
1100
fputs( auxstr, f2 );
1102
fprintf( f2, " P%u86 +", opmach[i+j] );
1103
if ( optype[i + j] >= OPTYPES) {
1104
fprintf( f2, " MN_%s", mnlist[opinfo[i+j]].string );
1106
fprintf( f2, " %04xh", opinfo[i+j] );
1109
fprintf( f2, "\t; %02x\n", i );
1111
auxstr = ";--- The rest of these are squeezed.\n" "\tdw 0,";
1112
for ( i = SPARSE_BASE, k = 1; i < NOPS; ++i ) {
1113
if ( (j = optype[i]) != 0 ) {
1114
fprintf( f2, auxstr );
1116
fprintf( f2, " P%u86 +", opmach[i] );
1118
fprintf( f2, " MN_%s", mnlist[opinfo[i]].string );
1120
fprintf( f2, " %04xh", opinfo[i] );
1122
if ( (k & 3) == 0 ) {
1123
fprintf( f2, "\t;%02X", k - 4 );
1133
fputs( "\n;--- table converts unsqueezed numbers to squeezed."
1134
"\n;--- 1E0-2DF are extended opcodes (0F xx).\n"
1135
"\n\nsqztab label byte\n", f2);
1138
for ( i = SPARSE_BASE; i < NOPS; i += 8 ) {
1139
if ( i == SPARSE_BASE + 256 )
1140
fprintf( f2, "\n;--- %u sparse groups\n\n", NSGROUPS );
1141
else if ( i == SPARSE_BASE + 256 + 8 * NSGROUPS ) {
1142
fprintf( f2, "\n;--- %u sparse fpu groups\n\n", NUMBER(sp_fpgrouptab) );
1143
fprintf( f2, "SFPGROUPS equ SPARSE_BASE + ( $ - sqztab )\n" );
1144
fprintf( f2, "SFPGROUP3 equ SFPGROUPS + 8 * 3\n" );
1147
for ( j = 0; j < 8; ++j ) {
1148
fprintf( f2, "%s%3d", auxstr, optype[i + j] == 0 ? 0 : ++k );
1151
fprintf( f2, "\t;%X\n", i );
1156
fputs( "\n;--- table of mnemonics that change in the "
1157
"presence of a WAIT" "\n;--- instruction.\n\n", f2 );
1158
put_dw( f2, "wtab1", startab_seq, n_star_entries );
1160
for ( i = 0; i < n_star_entries; ++i )
1161
startab_mn[i] = mnlist[startab_mn[i]].offset;
1162
put_dw( f2, "wtab2", startab_mn, n_star_entries );
1164
fputs( "wtab2 label word\n", f2 );
1165
for ( i = 0; i < n_star_entries; ++i )
1166
fprintf( f2, "\tdw MN_%s\n", mnlist[startab_mn[i]].string );
1168
fprintf( f2, "N_WTAB\tequ ($ - wtab2) / 2\n" );
1170
fputs( "\n;--- table for operands which have a different "
1171
"mnemonic for" "\n;--- their 32 bit versions (66h prefix).\n\n", f2 );
1172
put_dw( f2, "ltabo1", slashtab_seq, n_slash_entries );
1174
for ( i = 0; i < n_slash_entries; ++i )
1175
slashtab_mn[i] = mnlist[slashtab_mn[i]].offset;
1176
put_dw( f2, "ltabo2", slashtab_mn, n_slash_entries );
1178
fputs( "ltabo2 label word\n", f2 );
1179
for ( i = 0; i < n_slash_entries; ++i )
1180
fprintf( f2, "\tdw MN_%s\n", mnlist[slashtab_mn[i]].string );
1182
fprintf( f2, "N_LTABO\tequ ($ - ltabo2) / 2\n" );
1184
fputs( "\n;--- table for operands which have a different "
1185
"mnemonic for" "\n;--- their 32 bit versions (67h prefix).\n\n", f2 );
1186
put_dw( f2, "ltaba1", hashtab_seq, n_hash_entries );
1188
for ( i = 0; i < n_hash_entries; ++i )
1189
hashtab_mn[i] = mnlist[hashtab_mn[i]].offset;
1190
put_dw( f2, "ltaba2", hashtab_mn, n_hash_entries );
1192
fputs( "ltaba2 label word\n", f2 );
1193
for ( i = 0; i < n_hash_entries; ++i )
1194
fprintf( f2, "\tdw MN_%s\n", mnlist[hashtab_mn[i]].string );
1196
fprintf( f2, "N_LTABA\tequ ($ - ltaba2) / 2\n" );
1198
fputs( "\n;--- table of lockable instructions\n\n" , f2 );
1199
put_dw( f2, "locktab label word\n", locktab, n_locktab );
1200
fprintf( f2, "N_LOCK\tequ ($ - locktab) / 2\n\n" );
1207
int main( int argc, char *argv[] )
1215
printf("this program reads files instr.* to generate\nassembly include files " AsmTbl ".inc & " DisTbl ".inc\n");
1220
f1 = openread( "instr.key" );
1221
offset = OPTYPES + 1;
1222
while ( getline( f1 ) ) {
1224
char *q = strchr( p, ';' );
1230
while ( q > p && (*q == ' ' || *q == '\t') ) {
1236
if ( n_keys >= MAX_OL_TYPES )
1237
fail("Too many keys.");
1238
olkeydict[n_keys].key = getkey( &p );
1240
for ( i = 0;; ++i ) {
1241
if ( i >= n_ol_types ) {
1242
char *q = xmalloc( strlen( p ) + 1, "operand type name" );
1245
if ( n_ol_types >= MAX_OL_TYPES )
1246
fail( "Too many operand list types." );
1247
olnames[n_ol_types] = q;
1248
oloffset[n_ol_types] = offset;
1252
if ( q == NULL ) break;
1258
if ( strcmp(p, olnames[i]) == 0 )
1261
olkeydict[n_keys].value = i;
1262
olkeydict[n_keys].width = 1;
1263
if ( strstr( p, "OP_ALL" ) != NULL )
1264
olkeydict[n_keys].width = 2;
1265
else if ( strstr( p, "OP_R_ADD" ) != NULL )
1266
olkeydict[n_keys].width = 8;
1270
if ( offset >= 256 ) {
1271
fprintf( stderr, "%d bytes of operand lists. That's too many.\n",
1278
f1 = openread( "instr.ord" );
1279
while ( getline( f1 ) ) {
1282
if ( n_ords >= MAX_N_ORDS )
1283
fail ( "Too many ordering restrictions." );
1284
keyord1[n_ords] = lookupkey( getkey( &p ) );
1286
keyord2[n_ords] = lookupkey( getkey( &p ) );
1288
fail( "Syntax error in ordering file." );
1295
f1 = openread( "instr.set" );
1301
f2 = fopen( AsmTbl ".tmp", "w" );
1303
dumptablesAsm( f2 );
1306
remove( AsmTbl ".old" );
1307
if ( rename( AsmTbl ".inc", AsmTbl ".old" ) == -1 ) {
1308
perror( "rename " AsmTbl ".inc -> " AsmTbl ".old" );
1310
if ( rename( AsmTbl ".tmp", AsmTbl ".inc" ) == -1 ) {
1311
perror( "rename " AsmTbl ".tmp -> " AsmTbl ".inc" );
1314
perror( AsmTbl ".tmp" );
1320
f2 = fopen( DisTbl ".tmp", "w" );
1322
dumptablesDis( f2 );
1324
remove( DisTbl ".old" );
1325
if ( rename( DisTbl ".inc", DisTbl ".old" ) == -1 ) {
1326
perror( "rename " DisTbl ".inc -> " DisTbl ".old" );
1328
if ( rename( DisTbl ".tmp", DisTbl ".inc" ) == -1 ) {
1329
perror( "rename " DisTbl ".tmp -> " DisTbl ".inc" );
1332
perror( DisTbl ".tmp" );