DOS-debug

Форк
0
/
MKTABLES.C 
1339 строк · 34.8 Кб
1
/*
2
 * This program reads in the various data files, performs some checks,
3
 * and spits out the tables needed for assembly and disassembly.
4
 *
5
 * The input files are:
6
 *      instr.set   Instruction set
7
 *      instr.key   Translation from one- or two-character keys to
8
 *                  operand list types
9
 *      instr.ord   Ordering relations to enforce on the operands
10
 *
11
 * The output tables are written to ASMTBL.INC/DISTBL.INC, which are
12
 * included into DEBUG.ASM.
13
 */
14

15
#include <stdlib.h>
16
#include <stdio.h>
17
#include <stdarg.h>
18
#include <string.h>
19
#include <ctype.h>
20
#include <errno.h>
21

22
#define MAX_OL_TYPES        82
23
#define MAX_N_ORDS          30
24
#define LINELEN            132
25
#define MAX_ASM_TAB       2048
26
#define MAX_MNRECS         400
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
33
#define MSHIFT              12 /* number of bits below machine type */
34
#define SORTMN              0  /* sort mnemonics */
35

36
typedef char    Boolean;
37
#define True    1
38
#define False   0
39

40
#define NUMBER(x)   (sizeof(x) / sizeof(*x))
41

42
#define AsmTbl "asmtbl"
43
#define DisTbl "distbl"
44

45
static char line[LINELEN];
46
static const char *filename;
47
static int lineno;
48

49
static int n_keys = 0;
50
struct keytab {
51
 short key;  /* */
52
 short value;
53
 short width;
54
};
55

56
static int n_ol_types = 0;
57
static struct keytab olkeydict[MAX_OL_TYPES];
58
static char *olnames[MAX_OL_TYPES];  /* containes lines of INSTR.KEY */
59
static int oloffset[MAX_OL_TYPES];
60

61
static int n_ords = 0;
62
static struct keytab *keyord1[MAX_N_ORDS];
63
static struct keytab *keyord2[MAX_N_ORDS];
64
static Boolean ordsmall[MAX_OL_TYPES];
65

66
/*
67
 * Equates for the assembler table.
68
 * These should be the same as in debug.asm.
69
 */
70

71
#define ASM_END     0xff
72
#define ASM_DB      0xfe
73
#define ASM_DW      0xfd
74
#define ASM_DD      0xfc
75
#define ASM_ORG     0xfb
76
#define ASM_WAIT    0xfa
77
#define ASM_D32     0xf9
78
#define ASM_D16     0xf8
79
#define ASM_AAX     0xf7
80
#define ASM_SEG     0xf6
81
#define ASM_LOCKREP 0xf5
82
#define ASM_LOCKABLE    0xf4
83
#define ASM_MACH6   0xf3
84
#define ASM_MACH0   0xed
85

86
static int n_asm_tab = 0;
87
static unsigned char asmtab[MAX_ASM_TAB];
88

89
struct mnrec {
90
	struct mnrec *next;
91
	char  *string;
92
	short len;
93
	short offset;    /* ??? */
94
	short asmoffset; /* offset in asmtab */
95
};
96

97
static int num_mnrecs;
98
static struct mnrec mnlist[MAX_MNRECS];
99
static struct mnrec *mnhead;
100

101
static int n_saved_mnems = 0;
102
static int saved_mnem[MAX_SAVED_MNEMS];
103

104
static int n_slash_entries;
105
static int slashtab_seq[MAX_SLASH_ENTRIES];
106
static int slashtab_mn[MAX_SLASH_ENTRIES];
107

108
static int n_hash_entries;
109
static int hashtab_seq[MAX_HASH_ENTRIES];
110
static int hashtab_mn[MAX_HASH_ENTRIES];
111

112
static int n_star_entries;
113
static int startab_seq[MAX_STAR_ENTRIES];
114
static int startab_mn[MAX_STAR_ENTRIES];
115

116
static int n_locktab;
117
static int locktab[MAX_LOCKTAB_ENTRIES];
118

119
static int n_agroups;
120
static int agroup_i[MAX_AGROUP_ENTRIES];
121
static int agroup_inf[MAX_AGROUP_ENTRIES];
122

123
/*
124
 * Data and setup stuff for the disassembler processing.
125
 */
126

127
/* Data on coprocessor groups */
128

129
static unsigned int fpgrouptab[] = {0xd9e8, 0xd9f0, 0xd9f8};
130

131
#define NGROUPS     9
132

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))
137

138
/* #define OPILLEGAL 0 */
139
#define OPTWOBYTE   2
140
#define OPGROUP     4
141
#define OPCOPR      6
142
#define OPFPGROUP   8
143
#define OPPREFIX    10
144
#define OPSIMPLE    12
145
#define OPTYPES     12  /* op types start here (includes simple ops) */
146

147
#define PRESEG      1   /* these should be the same as in debug.asm */
148
#define PREREP      2
149
#define PREREPZ     4
150
#define PRELOCK     8
151
#define PRE32D      0x10
152
#define PRE32A      0x20
153

154
/*
155
 * For sparsely filled parts of the opcode map, we have counterparts
156
 * to the above, which are compressed in a simple way.
157
 */
158

159
/* Sparse coprocessor groups */
160

161
static unsigned int sp_fpgrouptab[] = {
162
	0xd9d0, 0xd9e0, 0xdae8, 0xdbe0, 0xded8, 0xdfe0 };
163

164
#define NSGROUPS 5
165

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))
169

170
static int optype[NOPS];
171
static int opinfo[NOPS];
172
static unsigned char opmach[NOPS];
173

174
/*
175
 * Here are the tables for the main processor groups.
176
 */
177

178
static struct {
179
	int seq;	/* sequence number of the group */
180
	int info;	/* which group number it is */
181
} grouptab[]= {
182
	{ 0x80, GROUP(1) }, /* Intel group 1 */
183
	{ 0x81, GROUP(1) },
184
	{ 0x83, GROUP(2) },
185
	{ 0xd0, GROUP(3) }, /* Intel group 2 */
186
	{ 0xd1, GROUP(3) },
187
	{ 0xd2, GROUP(4) },
188
	{ 0xd3, GROUP(4) },
189
	{ 0xc0, GROUP(5) }, /* Intel group 2a */
190
	{ 0xc1, GROUP(5) },
191
	{ 0xf6, GROUP(6) }, /* Intel group 3 */
192
	{ 0xf7, GROUP(6) },
193
	{ 0xff, GROUP(7) }, /* Intel group 5 */
194
	{ SPARSE_BASE + 0x00, GROUP(8) }, /* Intel group 6 */
195
	{ SPARSE_BASE + 0x01, GROUP(9) }  /* Intel group 7 */
196
};
197

198
/* #define NGROUPS 9 (this was done above) */
199

200
static struct { /* sparse groups */
201
	int seq; /* sequence number of the group */
202
	int info; /* which group number it is */
203
} sp_grouptab[] = {
204
	{ 0xfe, SGROUP(1) }, /* Intel group 4 */
205
	{ SPARSE_BASE+0xba, SGROUP(2) }, /* Intel group 8 */
206
	{ SPARSE_BASE+0xc7, SGROUP(3) }, /* Intel group 9 */
207
	{ 0x8f, SGROUP(4) }, /* Not an Intel group */
208
	{ 0xc6, SGROUP(5) }, /* Not an Intel group */
209
	{ 0xc7, SGROUP(5) }
210
};
211

212
/* #define NSGROUPS 5 (this was done above) */
213

214
/* strings to put into comment fields */
215

216
static struct inforec {
217
	int seqno;
218
	char *string;
219
} tblcomments[] = {
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" },
237
	{ -1, NULL }
238
};
239

240
static char *spectab[] = { "WAIT", "ORG", "DD", "DW", "DB" };
241
static char *spectab2[] = { "LOCKREP", "SEG" };
242

243
/*
244
 * terminate program with error msg.
245
 */
246

247
static volatile void fail( const char *message, ... )
248
/////////////////////////////////////////////////////
249
{
250
	va_list args;
251

252
	va_start( args, message );
253
	vfprintf( stderr, message, args );
254
	va_end( args );
255
	putc( '\n', stderr );
256
	exit( 1 );
257
}
258

259
static FILE * openread( const char *path )
260
//////////////////////////////////////////
261
{
262
	FILE *f;
263

264
	f = fopen( path, "r" );
265
	if ( f == NULL ) {
266
	    perror( path );
267
	    exit( 1 );
268
	}
269
	filename = path;
270
	lineno = 0;
271
	return f;
272
}
273

274
static volatile void linenofail( const char *message, ... )
275
///////////////////////////////////////////////////////////
276
{
277
	va_list args;
278

279
	fprintf( stderr, "Line %d of `%s':  ", lineno, filename );
280
	va_start( args, message );
281
	vfprintf( stderr, message, args );
282
	va_end( args );
283
	putc( '\n', stderr );
284
	exit( 1 );
285
}
286

287
static void * xmalloc( unsigned int len, const char *why )
288
//////////////////////////////////////////////////////////
289
{
290
	void *ptr = malloc( len );
291

292
	if ( ptr == NULL ) fail( "Cannot allocate %u bytes for %s", len, why );
293
	return ptr;
294
}
295

296
/*
297
 * read a line from input file, skip comments and blank lines.
298
 */
299

300
static Boolean getline( FILE *ff )
301
//////////////////////////////////
302
{
303
	int n;
304

305
	for ( ;; ) {
306
		if ( fgets( line, LINELEN, ff ) == NULL ) return False;
307
		++lineno;
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;
314
		line[n] = '\0';
315
		return True;
316
	}
317
}
318

319
static short getkey( char **pp )
320
////////////////////////////////
321
{
322
	short key;
323
	char *p = *pp;
324

325
	if (*p == ' ' || *p == '\t' || *p == ';' || *p == '\0')
326
	    linenofail("key expected");
327
	key = *p++;
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");
332
	}
333
	*pp = p;
334
	return key;
335
}
336

337
/*
338
 * Mark the given key pointer as small, as well as anything smaller than
339
 * it (according to instr.ord).
340
 */
341

342
static void marksmall( struct keytab *kp )
343
//////////////////////////////////////////
344
{
345
	int i;
346

347
	ordsmall[kp - olkeydict] = True;
348
	for ( i = 0; i < n_ords; ++i )
349
		if ( keyord2[i] == kp )
350
			marksmall( keyord1[i] );
351
}
352

353
/*
354
 * Add a byte to the assembler table (asmtab).
355
 * The format of this table is described in a long comment in debug.asm,
356
 * somewhere within the mini-assembler.
357
 */
358

359
static void add_to_asmtab( unsigned char byte )
360
///////////////////////////////////////////////
361
{
362
	if ( n_asm_tab >= MAX_ASM_TAB )
363
		linenofail( "Assembler table overflow." );
364
	asmtab[n_asm_tab++] = byte;
365
}
366

367

368
static unsigned char getmachine( char **pp )
369
////////////////////////////////////////////
370
{
371
	char *p = *pp;
372
	unsigned char value;
373

374
	if ( *p != ';' ) return 0;
375
	++p;
376
	if ( *p < '0' || *p > '6' )
377
		linenofail( "bad machine type" );
378
	value = *p++ - '0';
379
	add_to_asmtab( (unsigned char)(ASM_MACH0 + value) );
380
	*pp = p;
381
	return value;
382
}
383

384
static struct keytab * lookupkey( short key )
385
/////////////////////////////////////////////
386
{
387
	struct keytab *kp;
388

389
	for ( kp = olkeydict; kp < olkeydict + NUMBER(olkeydict); ++kp )
390
		if ( key == kp->key )
391
			return kp;
392
	linenofail( "can't find key %X", key );
393
	return NULL;
394
}
395

396
static char * skipwhite( char *p )
397
//////////////////////////////////
398
{
399
	while ( *p == ' ' || *p == '\t' ) ++p;
400
	return p;
401
}
402

403
/*
404
 * Creates an entry in the disassembler lookup table.
405
 */
406

407
static void entertable( int i, int type, int info )
408
///////////////////////////////////////////////////
409
{
410
	if ( optype[i] != 0 )
411
		linenofail( "Duplicate information for index %d", i );
412
	optype[i] = type;
413
	opinfo[i] = info;
414
}
415

416
/*
417
 * Get a hex nybble from the input line or fail.
418
 */
419

420
static int getnybble( char c )
421
//////////////////////////////
422
{
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 );
426
	return -1;
427
}
428

429
/*
430
 * Get a hex byte from the input line and update the pointer accordingly.
431
 */
432

433
static int getbyte( char **pp )
434
///////////////////////////////
435
{
436
	char *p = *pp;
437
	int answer;
438

439
	answer = getnybble( *p++ );
440
	answer = (answer << 4) | getnybble( *p++ );
441
	*pp = p;
442
	return answer;
443
}
444

445
/*
446
 * Get a `/r' descriptor from the input line and update the pointer
447
 * accordingly.
448
 */
449

450
static int getslash( char **pp )
451
////////////////////////////////
452
{
453
	char *p = *pp;
454
	int answer;
455

456
	if ( *p != '/' ) linenofail( "`/' expected" );
457
	++p;
458
	if ( *p < '0' || *p > '7' ) linenofail( "Octal digit expected" );
459
	answer = *p - '0';
460
	++p;
461
	*pp = p;
462
	return answer;
463
}
464

465
/*
466
 * enter item into mnlist[].
467
 */
468

469
static int entermn(char *str, char *str_end)
470
////////////////////////////////////////////
471
{
472
	char *p;
473

474
	if ( num_mnrecs >= MAX_MNRECS )
475
		linenofail( "Too many mnemonics" );
476

477
	if ( *str == '+' ) {
478
		if ( n_saved_mnems >= MAX_SAVED_MNEMS )
479
			linenofail( "Too many mnemonics to save" );
480
		saved_mnem[n_saved_mnems++] = num_mnrecs;
481
		++str;
482
	}
483

484
	p = xmalloc( str_end - str + 1, "mnemonic name" );
485
	mnlist[num_mnrecs].string = p;
486
	mnlist[num_mnrecs].len = str_end - str;
487
#ifdef NOSTRUPR
488
	while ( str < str_end ) *p++ = toupper( *str++ );
489
	*p = 0;
490
#else
491
	memcpy( p, str, str_end - str );
492
	*(p+(str_end - str)) = 0;
493
	_strupr( p );
494
#endif
495
	mnlist[num_mnrecs].asmoffset = n_asm_tab;
496
	return num_mnrecs++;
497
}
498

499
/*
500
 * Merge sort the indicated range of mnemonic records.
501
 */
502
#if SORTMN
503
static struct mnrec * mn_sort(struct mnrec *start, int len)
504
///////////////////////////////////////////////////////////
505
{
506
	struct mnrec *p1, *p2, *answer;
507
	struct mnrec **headpp;
508
	int i;
509

510
	i = len / 2;
511
	if (i == 0)
512
		return start;
513

514
	p1 = mn_sort(start, i);
515
	p2 = mn_sort(start + i, len - i);
516
	headpp = &answer;
517
	for ( ;; ) {
518
		if ( strcmp(p1->string, p2->string) < 0 ) {
519
			*headpp = p1;
520
			headpp = &p1->next;
521
			p1 = *headpp;
522
			if ( p1 == NULL ) {
523
				*headpp = p2;
524
				break;
525
			}
526
		} else {
527
			*headpp = p2;
528
			headpp = &p2->next;
529
			p2 = *headpp;
530
			if ( p2 == NULL ) {
531
				*headpp = p1;
532
				break;
533
			}
534
		}
535
	}
536
	return answer;
537
}
538
#endif
539

540
/*
541
 * This reads the main file, "instr.set".
542
 */
543

544
static void read_is( FILE *f1 )
545
///////////////////////////////
546
{
547
	int i;
548

549
	entertable( 0x0f, OPTWOBYTE, SPARSE_BASE );
550
	entertable( 0x26, OPPREFIX, PRESEG | (0 << 8) ); /* seg es */
551
	entertable( 0x2e, OPPREFIX, PRESEG | (1 << 8) ); /* seg cs */
552
	entertable( 0x36, OPPREFIX, PRESEG | (2 << 8) ); /* seg ss */
553
	entertable( 0x3e, OPPREFIX, PRESEG | (3 << 8) ); /* seg ds */
554
	entertable( 0x64, OPPREFIX, PRESEG | (4 << 8) ); /* seg fs */
555
	entertable( 0x65, OPPREFIX, PRESEG | (5 << 8) ); /* seg gs */
556
	entertable( 0xf2, OPPREFIX, PREREP ); /* other prefixes */
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;
562
	
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;
572

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));
577
	}
578
	for ( i = 0; i < NUMBER(sp_fpgrouptab); ++i ) {
579
		unsigned int j = sp_fpgrouptab[i];
580
		unsigned int k = (j >> 8) - 0xd8;
581

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));
586
	}
587

588
	/* loop over lines in the file */
589

590
	while ( getline( f1 ) ) {
591
		int mnem;
592
		int mn_alt;
593
		char *p, *p0, *pslash, *phash, *pstar;
594
		Boolean asm_only_line;
595
		unsigned char atab_addendum;
596

597
		asm_only_line = False;
598
		p0 = line;
599
		if ( line[0] == '_' ) {
600
			asm_only_line = True;
601
			++p0;
602
		}
603
		atab_addendum = '\0';
604
		if ( *p0 == '^' ) {
605
			static const unsigned char uptab[] =
606
			{ASM_AAX, ASM_DB, ASM_DW,
607
			ASM_DD, ASM_ORG, ASM_D32};
608

609
			++p0;
610
			atab_addendum = uptab[*p0++ - '0'];
611
		}
612
		p = strchr( p0, ' ' );
613
		if ( p == NULL ) p = p0 + strlen( p0 );
614

615
		/* check for '/', '#' and '*' separators */
616

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 );
623
			/* ++mnlist[mnem].asmoffset;*/	/* this one isn't 32 bit */
624
			++pslash;
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 );
630
			/* ++mnlist[mnem].asmoffset;*/	/* this one isn't 32 bit */
631
			++phash;
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 );	/* note the reversal */
636
			add_to_asmtab( (unsigned char)ASM_WAIT );
637
			++pstar;
638
			mnem = entermn( pstar, p );
639
		} else {
640
			mnem = entermn( p0, p );
641
		}
642

643
		if ( atab_addendum != '\0' ) add_to_asmtab( atab_addendum );
644

645
		atab_addendum = ASM_END;
646
		memset( ordsmall, 0, n_keys * sizeof(Boolean) );
647

648
		/* loop over instruction variants */
649

650
		while ( *p == ' ' ) {
651
			Boolean lockable;
652
			Boolean asm_only;
653
			Boolean dis_only;
654
			unsigned char	machine;
655
			unsigned long	atab_inf;
656
			unsigned short	atab_key;
657
			unsigned char	atab_xtra = 0;
658

659
			while ( *p == ' ' ) ++p;
660
			asm_only = asm_only_line;
661
			dis_only = False;
662
			if ( *p == '_' ) { /* if assembler only */
663
				++p;
664
				asm_only = True;
665
			}
666
			else if ( *p == 'D' ) { /* if disassembler only */
667
				++p;
668
				dis_only = True;
669
			}
670
			lockable = False;
671
			if ( *p == 'L' ) {
672
				++p;
673
				lockable = True;
674
				if ( dis_only == False )
675
					add_to_asmtab( (unsigned char)ASM_LOCKABLE );
676
			}
677
			atab_inf = i = getbyte( &p );
678
			if ( i == 0x0f ) {
679
				i = getbyte( &p );
680
				atab_inf = 256 + i;
681
				i += SPARSE_BASE;
682
			}
683
			if ( optype[i] == OPGROUP ) {
684
				int j = getslash( &p );
685
				int k;
686

687
				for ( k = 0;; ++k ) {
688
					if ( k >= n_agroups ) {
689
						if ( ++n_agroups > MAX_AGROUP_ENTRIES )
690
							linenofail( "Too many agroup entries" );
691
						agroup_i[k] = i;
692
						agroup_inf[k] = atab_inf;
693
						break;
694
					}
695
					if ( agroup_i[k] == i )
696
						break;
697
				}
698
				atab_inf = 0x240 + 8 * k + j;
699
				i = opinfo[i] + j;
700
			}
701
			if ( optype[i] == OPCOPR ) {
702
				if ( *p == '/' ) {
703
					int j = getslash( &p );
704

705
					atab_inf = 0x200 + j * 8 + (i - 0xd8);
706
					i = opinfo[i] + j;
707
				} else {
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);
714
				}
715
			}
716
			switch ( *p++ ) {
717
			case '.':
718
				machine = getmachine( &p );
719
				if ( !asm_only ) {
720
					entertable( i, OPSIMPLE, mnem );
721
					opmach[i] = machine;
722
				}
723
				atab_key = 0;
724
				/* none of these are lockable */
725
				break;
726
			case '*':	/* lock or rep... prefix */
727
				add_to_asmtab( (unsigned char)ASM_LOCKREP );
728
				add_to_asmtab( (unsigned char)atab_inf );	/* special case */
729
				atab_addendum = '\0';
730
				break;
731
			case '&':	/* segment prefix */
732
				add_to_asmtab( (unsigned char)ASM_SEG );
733
				add_to_asmtab( (unsigned char)atab_inf );	/* special case */
734
				atab_addendum = '\0';
735
				break;
736
			case ':': {
737
				struct keytab *kp = lookupkey(getkey(&p));
738
				int width = kp->width;
739
				int j;
740

741
				machine = getmachine(&p);
742
				if ( dis_only )
743
					; /*atab_addendum = '\0'; */
744
				else {
745
					if ( ordsmall[kp - olkeydict] )
746
						linenofail( "Variants out of order." );
747
					marksmall( kp );
748
				}
749
				atab_key = kp->value + 1;
750
				if ( ( i >= 256 && i < SPARSE_BASE )
751
					|| i >= SPARSE_BASE + 256 ) {
752
					if ( width > 2 )
753
						linenofail( "width failure" );
754
					width = 1;
755
				}
756
				if ( i & ( width - 1 ) )
757
					linenofail( "width alignment failure" );
758
				if ( !asm_only )
759
					for ( j = ( i == 0x90 ); j < width; ++j ) {
760
						/*      ^^^^^^^^^  kludge for NOP instr. */
761
						entertable(i|j, oloffset[kp->value], mnem);
762
						opmach[i | j] = machine;
763
						if ( lockable ) {
764
							if ( n_locktab >= MAX_LOCKTAB_ENTRIES )
765
								linenofail("Too many lockable "
766
										"instructions");
767
							locktab[n_locktab] = i | j;
768
							++n_locktab;
769
						}
770
					}
771
			}
772
			break;
773
			default:
774
				linenofail("Syntax error.");
775
			}
776
			if ( atab_addendum != '\0' && dis_only == False ) {
777
				atab_inf = atab_inf * (unsigned short) (n_ol_types + 1)
778
					+ atab_key;
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 );
785
			}
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;
791
				++n_slash_entries;
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;
797
				++n_hash_entries;
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;
803
				++n_star_entries;
804
			}
805
		} /* end while variants */
806
		if ( *p != '\0' )
807
			linenofail( "Syntax error." );
808
		if ( atab_addendum != '\0' ) {
809
			add_to_asmtab( atab_addendum );	/* ASM_END, if applicable */
810
		}
811
	}
812
}
813

814
/* Print a labeled "dw" list; add a newline every 8 items. */
815

816
static void put_dw( FILE *f2, const char *label, int *datap, int n )
817
////////////////////////////////////////////////////////////////////
818
{
819
	const char *initstr;
820
	int i;
821

822
	fputs(label,f2);
823
	while (n > 0) {
824
		initstr = "\tdw ";
825
		for (i = (n <= 8 ? n : 8); i > 0; --i) {
826
			fputs(initstr, f2);
827
			initstr = ",";
828
			fprintf( f2, "0%xh", *datap++);
829
		}
830
		fputs("\n", f2);
831
		n -= 8;
832
	}
833
}
834

835
/*
836
 * Print the assembler infos onto the file.
837
 */
838

839
static void dumptablesAsm(FILE *f2)
840
///////////////////////////////////
841
{
842
	int offset;
843
	struct mnrec *mnp;
844
	int colsleft;
845
	char *auxstr;
846
	struct inforec *tblptr;
847
	int i;
848
	int j;
849
	unsigned int k;
850
	unsigned int l;
851
	char *pmne;
852

853
	if ( num_mnrecs == 0 )
854
		fail( "No assembler mnemonics!" );
855

856
#if SORTMN
857
	/* Sort the mnemonics alphabetically. */
858
	mnhead = mn_sort(mnlist, num_mnrecs);
859
#else
860
	mnhead = mnlist;
861
	for ( i = 0; i < num_mnrecs; i++ )
862
		mnlist[i].next = &mnlist[i+1];
863
	mnlist[num_mnrecs-1].next = NULL;
864
#endif
865

866
	fprintf( f2, "\n;--- This file was generated by mktables.exe.\n" );
867

868
	/* Print out oplists[] */
869

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 ) {
875
#if 0
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);
880
			szKey[2] = '\0';
881
		} else {
882
			szKey[0] = (unsigned char)(olkeydict[i].key);
883
			szKey[1] = '\0';
884
		}
885
		fprintf( f2, "\topl %s, %s\t; ofs=%Xh\n", szKey, olnames[i], oloffset[i] );
886
#else
887
		fprintf( f2, "\topl %02X,%s\t; idx=%u, ofs=%Xh\n", i+1, olnames[i], i+1, oloffset[i] );
888
#endif
889
	}
890

891
	fprintf( f2, "\nASMMOD\tEQU %0Xh\n", n_ol_types+1 );
892
//	fprintf( f2, "\nASMMOD\tEQU opidx\n" );
893

894
	/* Dump out agroup_inf. */
895

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 );
901
	}
902

903
	/* Dump out asmtab. */
904

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 );
917

918
		i = mnp->asmoffset;
919

920
		if ( asmtab[i] == ASM_D16 && asmtab[i+1] == ASM_D32 ) {
921
			/* fprintf( f2, ", ASM_D16\t; ofs=%04x\n", i ); */
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 );
927
		} else {
928
			j = i;
929
			while ( asmtab[j] > ASM_SEG && asmtab[j] < ASM_WAIT ) {
930
				switch ( asmtab[j] ) {
931
				case ASM_AAX:
932
					fprintf( f2, ", ASM_AAX" );
933
					break;
934
				case ASM_D16:
935
					fprintf( f2, ", ASM_D16" );
936
					break;
937
				case ASM_D32:
938
					fprintf( f2, ", ASM_D32" );
939
					break;
940
				}
941
				j++;
942
			}
943
			fprintf( f2, "\t; ofs=%Xh\n", i );
944

945
			for ( ; j < n_asm_tab; ) {
946
				char *lockstr = "";
947
				char machstr[12] = {""};
948
				if ( asmtab[j] == 0xFF )
949
					break;
950

951
				if ( asmtab[j] == ASM_LOCKABLE ) {
952
					lockstr = "ASM_LOCKABLE";
953
					j++;
954
				}
955
				/* there's a problem with DEC and INC! */
956
				if ( asmtab[j] == 0xFF )
957
					break;
958
				if ( asmtab[j] >= ASM_MACH0 && asmtab[j] <= ASM_MACH6 ) {
959
					sprintf( machstr, "ASM_MACH%u", asmtab[j] - ASM_MACH0 );
960
					j++;
961
				}
962

963
				k = (int)asmtab[j] * 256 + asmtab[j+1];
964
				l = k % (n_ol_types+1);
965
				k = k / (n_ol_types+1);
966

967
				if ( k >= 0xD8 && k <= 0xDF )
968
					fprintf( f2, "\t fpvariant " );
969
				else
970
					fprintf( f2, "\t variant " );
971

972
				if ( k >= 0x240 )
973
					fprintf( f2, "AGRP(%u,%u), %u", (k - 0x240) >> 3, (k - 0x240) & 7, l );
974
				else
975
					fprintf( f2, "%03xh, %u", k, l );
976
				j += 2;
977

978
				if ( k >= 0xD8 && k <= 0xDF) {
979
					fprintf( f2, ", %03xh", asmtab[j] );
980
					j++;
981
				}
982
				if ( *lockstr == '\0' && machstr[0] == '\0' )
983
					fprintf( f2, "\n" );
984
				else if ( machstr[0] == '\0' )
985
					fprintf( f2, ", %s\n", lockstr );
986
				else
987
					fprintf( f2, ", %s, %s\n", lockstr, machstr );
988
			}
989
			fprintf( f2, "\t endvariant\n");
990
			i = j;
991
		}
992

993
	}
994
	fputs( "\nend_mnlist label byte\n\n", f2);
995

996
	if (offset >= (1 << MSHIFT)) {
997
		fprintf(stderr, "%d bytes of mnemonics.  That's too many.\n", offset);
998
		exit(1);
999
	}
1000

1001
}
1002

1003
/*
1004
 * Print the disassembler infos onto the file.
1005
 */
1006

1007
static void dumptablesDis(FILE *f2)
1008
///////////////////////////////////
1009
{
1010
	int offset;
1011
	char *auxstr;
1012
	struct inforec *tblptr;
1013
	int i;
1014
	int j;
1015
	unsigned int k;
1016
	unsigned int l;
1017
	char *pmne;
1018

1019
	fprintf( f2, "\n;--- This file was generated by mktables.exe.\n\n" );
1020

1021
	/* Print out optype[]. */
1022

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);
1028
	auxstr = "\n\tdb ";
1029
	tblptr = tblcomments;
1030

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 ) {
1035
				int y = 0;
1036
				if ( optype[i + j] > OPTYPES )
1037
					for ( y = 1; y <= n_ol_types; y++ )
1038
						if ( oloffset[y-1] == optype[i + j] )
1039
							break;
1040
				if ( y <= n_ol_types )
1041
					fprintf( f2, "OT(%02X)", y );
1042
				else
1043
					fail("offset not found for %u: %X", i+j, optype[i+j] );
1044
			} else
1045
				fprintf( f2, "  %03Xh", optype[i + j] );
1046
			auxstr = ",";
1047
		}
1048
		fprintf( f2, "\t; %02x - %02x", i, i + 7 );
1049
		if ( i == tblptr->seqno ) {
1050
			fprintf( f2, " (%s)", (tblptr++)->string );
1051
		}
1052
		auxstr = "\n\tdb ";
1053
	}
1054

1055
	fprintf( f2, "\nSPARSE_BASE\tequ $ - optypes\n" );
1056

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 ) {
1060
			/* int y = 0; */
1061
			if ( j >= OPTYPES ) {
1062
				int y = 0;
1063
				if ( j > OPTYPES )
1064
					for ( y = 1; y <= n_ol_types; y++ )
1065
						if ( oloffset[y-1] == j )
1066
							break;
1067
				if ( y <= n_ol_types)
1068
					fprintf( f2, "%sOT(%02X)", auxstr, y );
1069
				else
1070
					fail("offset not found for %u: %X", i, j );
1071
			} else
1072
				fprintf( f2, "%s  %03Xh", auxstr, j );
1073
			k++;
1074
			if ( (k & 7) == 0 ) {
1075
				fprintf( f2, "\t;%02X", k-8 );
1076
				auxstr = "\n\tdb ";
1077
			} else
1078
				auxstr = ",";
1079
		}
1080
	fputs( "\n\nOTDATA ends\n", f2 );
1081

1082
	/* Print out opinfo[]. */
1083

1084
	fputs( "\n", f2 );
1085
	for ( i = 1; i < 7; i++ )
1086
		fprintf( f2, "P%u86\tequ %Xh\n", i, i << MSHIFT );
1087

1088
	fputs( "\n\talign 2\n", f2 );
1089

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 );
1096

1097
	for ( i = 0; i < SPARSE_BASE; i += 4 ) {
1098
		auxstr = "\tdw ";
1099
		for ( j = 0; j < 4; ++j ) {
1100
			fputs( auxstr, f2 );
1101
			if ( opmach[i+j] )
1102
				fprintf( f2, " P%u86 +", opmach[i+j] );
1103
			if ( optype[i + j] >= OPTYPES) {
1104
				fprintf( f2, " MN_%s", mnlist[opinfo[i+j]].string );
1105
			} else
1106
				fprintf( f2, " %04xh", opinfo[i+j] );
1107
			auxstr = ",";
1108
		}
1109
		fprintf( f2, "\t; %02x\n", i );
1110
	}
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 );
1115
			if (opmach[i])
1116
				fprintf( f2, " P%u86 +", opmach[i] );
1117
			if (j >= OPTYPES) {
1118
				fprintf( f2, " MN_%s", mnlist[opinfo[i]].string );
1119
			} else
1120
				fprintf( f2, " %04xh", opinfo[i] );
1121
			k++;
1122
			if ( (k & 3) == 0 ) {
1123
				fprintf( f2, "\t;%02X", k - 4 );
1124
				auxstr = "\n\tdw ";
1125
			} else
1126
				auxstr = ",";
1127
		}
1128
	}
1129
	fputs( "\n", f2 );
1130

1131
	/* Print out sqztab. */
1132

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);
1136

1137
	k = 0;
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" );
1145
		}
1146
		auxstr = "\tdb ";
1147
		for ( j = 0; j < 8; ++j ) {
1148
			fprintf( f2, "%s%3d", auxstr, optype[i + j] == 0 ? 0 : ++k );
1149
			auxstr = ",";
1150
		}
1151
		fprintf( f2, "\t;%X\n", i );
1152
	}
1153

1154
	/* Print out the cleanup tables. */
1155

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 );
1159
#if 0
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 );
1163
#else
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 );
1167
#endif
1168
	fprintf( f2, "N_WTAB\tequ ($ - wtab2) / 2\n" );
1169

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 );
1173
#if 0
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 );
1177
#else
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 );
1181
#endif
1182
	fprintf( f2, "N_LTABO\tequ ($ - ltabo2) / 2\n" );
1183

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 );
1187
#if 0
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 );
1191
#else
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 );
1195
#endif
1196
	fprintf( f2, "N_LTABA\tequ ($ - ltaba2) / 2\n" );
1197

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" );
1201

1202
}
1203
/* main() - read and process files instr.key, instr.ord, instr.set
1204
 * and then dump asmtbl.inc and dasmtbl.inc.
1205
 */
1206

1207
int main( int argc, char *argv[] )
1208
//////////////////////////////////
1209
{
1210
	FILE *f1; /* input */
1211
	FILE *f2; /* output */
1212
	int offset;
1213

1214
	if (argc > 1) {
1215
		printf("this program reads files instr.* to generate\nassembly include files " AsmTbl ".inc & " DisTbl ".inc\n");
1216
		return 1;
1217
	}
1218
	/* Read in the key dictionary. */
1219

1220
	f1 = openread( "instr.key" );
1221
	offset = OPTYPES + 1;
1222
	while ( getline( f1 ) ) {
1223
		char *p = line;
1224
		char *q = strchr( p, ';' );
1225
		int i;
1226

1227
		if ( q ) {
1228
			*q = '\0';
1229
			q--;
1230
			while ( q > p && (*q == ' ' || *q == '\t') ) {
1231
				*q = '\0';
1232
				q--;
1233
			}
1234
		}
1235

1236
		if ( n_keys >= MAX_OL_TYPES )
1237
			fail("Too many keys.");
1238
		olkeydict[n_keys].key = getkey( &p );
1239
		p = skipwhite( p );
1240
		for ( i = 0;; ++i ) {
1241
			if ( i >= n_ol_types ) {
1242
				char *q = xmalloc( strlen( p ) + 1, "operand type name" );
1243

1244
				strcpy( q, p );
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;
1249
				for ( ;; ) {
1250
					++offset;
1251
					q = strchr(q, ',');
1252
					if ( q == NULL ) break;
1253
					++q;
1254
				}
1255
				++offset;
1256
				++n_ol_types;
1257
			}
1258
			if ( strcmp(p, olnames[i]) == 0 )
1259
				break;
1260
		}
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;
1267
		++n_keys;
1268
	}
1269
	fclose( f1 );
1270
	if ( offset >= 256 ) {
1271
		fprintf( stderr, "%d bytes of operand lists.  That's too many.\n",
1272
				offset );
1273
		exit( 1 );
1274
	}
1275

1276
	/* Read in the ordering relations. */
1277

1278
	f1 = openread( "instr.ord" );
1279
	while ( getline( f1 ) ) {
1280
		char *p = line;
1281

1282
		if ( n_ords >= MAX_N_ORDS )
1283
			fail ( "Too many ordering restrictions." );
1284
		keyord1[n_ords] = lookupkey( getkey( &p ) );
1285
		p = skipwhite(p);
1286
		keyord2[n_ords] = lookupkey( getkey( &p ) );
1287
		if ( *p != '\0' )
1288
			fail( "Syntax error in ordering file." );
1289
		++n_ords;
1290
	}
1291
	fclose( f1 );
1292

1293
	/* Do the main processing. */
1294

1295
	f1 = openread( "instr.set" );
1296
	read_is( f1 );
1297
	fclose( f1 );
1298

1299
	/* Write AsmTbl.inc */
1300

1301
	f2 = fopen( AsmTbl ".tmp", "w" );
1302
	if ( f2  ) {
1303
		dumptablesAsm( f2 );
1304
		fclose( f2 );
1305
		/* Move the file to its original position. */
1306
		remove( AsmTbl ".old" );
1307
		if ( rename( AsmTbl ".inc", AsmTbl ".old" ) == -1 ) {
1308
			perror( "rename " AsmTbl ".inc -> " AsmTbl ".old" );
1309
		}
1310
		if ( rename( AsmTbl ".tmp", AsmTbl ".inc" ) == -1 ) {
1311
			perror( "rename " AsmTbl ".tmp -> " AsmTbl ".inc" );
1312
		}
1313
	} else {
1314
		perror( AsmTbl ".tmp" );
1315
		exit( 1 );
1316
	}
1317

1318
	/* Write DisTbl.inc */
1319

1320
	f2 = fopen( DisTbl ".tmp", "w" );
1321
	if ( f2 ) {
1322
		dumptablesDis( f2 );
1323
		fclose( f2 );
1324
		remove( DisTbl ".old" );
1325
		if ( rename( DisTbl ".inc", DisTbl ".old" ) == -1 ) {
1326
			perror( "rename " DisTbl ".inc -> " DisTbl ".old" );
1327
		}
1328
		if ( rename( DisTbl ".tmp", DisTbl ".inc" ) == -1 ) {
1329
			perror( "rename " DisTbl ".tmp -> " DisTbl ".inc" );
1330
		}
1331
	} else {
1332
		perror( DisTbl ".tmp" );
1333
		exit( 1 );
1334
	}
1335

1336
	puts( "Done." );
1337

1338
	return 0;
1339
}
1340

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.