1#include "hppa-opcode.h"
2#include <stdio.h>
3
4extern uint32_t random();
5
6#define RANGE(number)	(random() % (number))
7#define COIN			(RANGE(2))
8#define IMM_NUM(range)	{ 	int tmp000111000usv = RANGE(range); \
9							if (tmp000111000usv == 0) \
10								printf(" %d", tmp000111000usv); \
11							else \
12								printf(" %c%d", (COIN) ? '-' : ' ',  \
13									tmp000111000usv); \
14						}
15
16
17/* The 'cond' decode table */
18
19typedef  struct  condition_decode {
20	char condition[4];
21}  condT;
22
23char *get_cond_str(const condT table[8][2], int c, int f );
24
25/* condition decode tables
26 * Refer to PA-RISC 1.1 Architecture and Instruction Set
27 * Reference Manual, Second edition, Sep. 1992, pp. 5-2 - 5-8.
28 */
29
30/* Note : In all the following tables
31 *        ""   ... never
32 *        "???"   ... Invalid combination
33 */
34
35/* compare/subtraclt instruction conditions */
36const condT c_comp_sub[8][2]  = { /* Table 5-3 */
37	{ "", "TR" },
38	{ "=", "<>" },
39	{ "<", ">=" },
40	{ "<=", ">" },
41	{ "<<", ">>=" },
42	{ "<<=", ">>" },
43	{ "SV", "NSV" },
44	{ "OD", "EV" }
45};
46
47/* add instruction conditions */
48const condT c_add[8][2]  = { /* Table 5-4 */
49	{ "", "TR" },
50	{ "=", "<>" },
51	{ "<", ">=" },
52	{ "<=", ">" },
53	{ "NUV", "UV"  },
54	{ "ZNV", "VNZ" },
55	{ "SV", "NSV" },
56	{ "OD", "EV" }
57};
58
59/* logical instruction conditions */
60const condT c_logical[8][2]  = { /* Table 5-5 */
61	{ "", "TR" },
62	{ "=", "<>" },
63	{ "<", ">=" },
64	{ "<=", ">" },
65	{ "???", "???" },
66	{ "???", "???" },
67	{ "???", "???" },
68	{ "OD", "EV" }
69};
70
71/* unit instruction conditions */
72const condT c_unit[8][2]  = { /* Table 5-6 */
73	{ "", "TR" },
74	{ "???", "???" },
75	{ "SBZ", "NBZ" },
76	{ "SHZ", "NHZ" },
77	{ "SDC", "NDC" },
78	{ "???", "???" },
79	{ "SBC", "NBC" },
80	{ "SHC", "NHC" }
81};
82
83/* shift/extract/deposit instruction conditions */
84const condT c_shift_extract_deposit[8][2]  = { /* Table 5-7 */
85	{ "", "???" },
86	{ "=", "???" },
87	{ "<", "???" },
88	{ "OD", "???" },
89	{ "TR", "???" },
90	{ "<>", "???" },
91	{ ">=", "???" },
92	{ "EV", "???" }
93};
94
95
96
97char *controlregs[] = { "fir", "psr", "epsr", "dirbase", "db", "fsr" };
98#define NCREGS	(sizeof controlregs / sizeof controlregs[0])
99
100char *textlabels[] = { "foo", "bar", "baz", "xork" };
101#define NTLABELS	(sizeof textlabels / sizeof textlabels[0])
102
103char *datalabels[] = { "data1", "data2", "data3", "data4" };
104#define NDLABELS	(sizeof datalabels / sizeof datalabels[0])
105
106char *fp_cmp_cond[] =	{
107	"false?","false", "true?", "true", "!<=>", "!?>=", "!?<=",
108	"!<>", "!>=", "!?>", "?<=", "!<=", "!?<", "?>=", "!?=",
109	"!=t", "<=>", "=t", "?=", "?<", "<=", "!>", "?>", ">=",
110	"!<", "<>", "!=", "!?", "?", "=", "<", ">"
111};
112#define NFPCOND	(sizeof fp_cmp_cond / sizeof fp_cmp_cond[0])
113
114char *fp_format_str[] = { "sgl", "dbl", "quad" };
115#define NFPFMT (sizeof fp_format_str / sizeof fp_format_str[0])
116
117/*
118 * Traverse the opcode table, dumping out sample instructions.
119 */
120void
121main()
122{
123	int i;
124	const char *arg;
125	int do_not_nullify = 0;
126
127	printf( "\t.text\n%s:", textlabels[0] );
128	/* a label at the begining of the file */
129	printf("label1:\n");
130
131	for ( i = 0; i < NUMOPCODES; ++i )
132	{
133		if ( i == (NUMOPCODES/3) )
134			printf( "%s:", textlabels[1] );
135		if ( i == (NUMOPCODES/2) )
136			printf( "%s:", textlabels[2] );
137
138		printf( "\t%s", pa_opcodes[i].name );
139
140		for ( arg = pa_opcodes[i].args; *arg != '\0'; ++arg )
141		{
142		    switch( *arg ) {
143
144			case '\0':  /* end of args */
145  				break;
146
147			case '(':   /* these must match exactly */
148				putchar(' '); /* and FALLTHRU  */
149			case ')':
150			case ',':
151			case ' ':
152				putchar(*arg);
153  				break;
154
155			case 'b':   /* 5 bit register field at 10 */
156			case 'x':   /* 5 bit register field at 15 */
157 			case 't':   /* 5 bit register field at 31 */
158			case 'v':   /* a 't' type extended to handle L/R register halves. */
159			case 'E':   /* a 'b' type extended to handle L/R register halves. */
160			case 'X':   /* an 'x' type extended to handle L/R register halves. */
161			case '4':   /* 5 bit register field at 10 (used in 'fmpyadd' and 'fmpysub') */
162			case '6':   /* 5 bit register field at 15 (used in 'fmpyadd' and 'fmpysub') */
163			case '7':   /* 5 bit register field at 31 (used in 'fmpyadd' and 'fmpysub') */
164			case '8':   /* 5 bit register field at 20 (used in 'fmpyadd' and 'fmpysub') */
165			case '9':   /* 5 bit register field at 25 (used in 'fmpyadd' and 'fmpysub') */
166				printf(" %%r%d", RANGE(32));
167 				break;
168
169			case 'r':   /* 5  bit immediate at 31 */
170			case 'R':   /* 5  bit immediate at 15 */
171				printf(" %d", RANGE(32));
172 				break;
173			case 'T':   /* 5 bit field length at 31 (encoded as 32-T) */
174				printf(" %d", RANGE(31) + 1);
175 				break;
176
177			case '5':   /* 5 bit immediate at 15 */
178			case 'V':   /* 5  bit immediate at 31 */
179			case 'p':   /* 5 bit shift count at 26 (to support SHD instr.) */
180						/* value is encoded in instr. as 31-p where p is   */
181						/* the value scanned here */
182			case 'P':   /* 5-bit bit position at 26 */
183			case 'Q':   /* 5  bit immediate at 10 (unsigned bit position */
184						/* value for the bb instruction) */
185				IMM_NUM(15);
186				continue;
187
188			case 's':   /* 2 bit space identifier at 17 */
189				printf(" %d", RANGE(4));
190				break;
191
192			case 'S':   /* 3 bit space identifier at 18 */
193				printf(" %%sr%d", RANGE(8));
194				break;
195
196			case 'c':   /* indexed load completer. */
197			{
198				int m, u, i;
199
200				m = COIN;
201				u = COIN;
202				i = 0;
203				if (COIN)
204					while (i < 2) {
205						if (m==1 && u==1) {
206							printf(",sm");
207							i++;
208						}
209						else if (m==1)
210							printf(",m");
211							else if (u==1)
212								printf(",s");
213								else /* m==0 && u==0 */ {
214									printf(",sm");
215									i++;
216								} /* probability distribution */
217						i++;
218  					}
219  				continue;
220			}
221			case 'C':   /* short load and store completer */
222				if (COIN)
223					if (COIN)
224						printf(",mb");
225					else
226						printf(",ma");
227				continue;
228			case 'Y':   /* Store Bytes Short completer */
229			{
230				int i = 0, m, a;
231				while ( i < 2 ) {
232					m = COIN;
233					a = COIN;
234
235					if (m==1) /* && (a==0 || a==1) */
236						printf(",m");
237					else if (a==0)  /* && m==0 */
238						printf(",b");
239						else if (a==1) /* && m==0 */
240							printf(",e");
241					i++;
242				}
243				continue;
244			}
245			case '<':   /* non-negated compare/subtract conditions. */
246			{
247				int cmpltr;
248
249				do {
250					cmpltr = RANGE(4);
251				} while (cmpltr == 0);
252
253				printf(",%s", get_cond_str(c_comp_sub, cmpltr, 0));
254			}
255				continue;
256			case '?':   /* negated or non-negated cmp/sub conditions. */
257					/* used only by ``comb'' and ``comib'' pseudo-ops */
258			case '-':   /* compare/subtract conditions */
259			{
260				int flag, cmpltr;
261				char *tmp;
262
263				do {
264					flag = COIN;
265					cmpltr = RANGE(8);
266				} while ((flag & cmpltr) == 0 || (cmpltr == 0));
267
268				tmp = get_cond_str(c_comp_sub, cmpltr, flag);
269
270				if (*tmp != '\0')
271					printf(",%s", tmp);
272			}
273				continue;
274			case '+':   /* non-negated add conditions */
275			case '!':   /* negated or non-negated add conditions. */
276			{
277				int flag, cmpltr;
278				char *tmp;
279
280				do {
281					flag = COIN;
282					cmpltr = RANGE(8);
283				} while ((flag & cmpltr) == 0 || (cmpltr == 0));
284
285				tmp = get_cond_str(c_add, cmpltr, flag);
286
287				if (COIN && (*tmp != '\0')) /* condition */ {
288						printf(",%s", tmp);
289						if (COIN) { /* nullify */
290							printf(",n ");
291							do_not_nullify = 1;
292						}
293				}
294			}
295				continue;
296			case '&':   /* logical instruction conditions */
297			{
298				int flag, cmpltr;
299				char *tmp;
300
301				flag = COIN;
302				do {
303					cmpltr = RANGE(8);
304				} while (cmpltr == 4 || cmpltr == 5 || cmpltr == 6);
305
306				tmp = get_cond_str(c_logical, cmpltr, flag);
307
308				if (COIN && (*tmp != '\0')) /* condition */
309					printf(",%s", tmp);
310			}
311				continue;
312			case 'U':   /* unit instruction conditions */
313			{
314				int flag, cmpltr;
315				char *tmp;
316
317				flag = COIN;
318				do {
319					cmpltr = RANGE(8);
320				} while (cmpltr == 1 || cmpltr == 5);
321
322				tmp = get_cond_str(c_unit, cmpltr, flag);
323				if (COIN && (*tmp != '\0')) /* condition */
324					printf(",%s", tmp);
325			}
326				continue;
327			case '>':   /* shift/extract/deposit conditions. */
328			{
329				int  cmpltr;
330				char *tmp;
331
332				cmpltr = RANGE(8);
333
334				tmp = get_cond_str(c_shift_extract_deposit, cmpltr, 0);
335
336				if (COIN && (*tmp != '\0')) /* condition */
337					printf(",%s", tmp);
338			}
339				continue;
340			case '~':   /* bvb,bb conditions */
341				if (COIN)
342					printf(",<");
343				else
344					printf(",>=");
345				continue;
346
347			case 'i':   /* 11 bit immediate at 31 */
348				IMM_NUM(1024);
349				continue;
350
351			case 'j':   /* 14 bit immediate at 31 --- LO14 */
352			case 'a':	/* for be, ble --- BR17*/
353			{
354				int field_selector = RANGE(3);
355				switch (field_selector) {
356				case 2:	/* field selector R`*/
357					printf(" R`");
358					break;
359				case 1:	/* field selector L`*/
360					printf(" L`");
361					break;
362				default:
363					break;
364				}
365				IMM_NUM(8192);
366				continue;
367			}
368			case 'k':   /* 21 bit immediate at 31 --- HI21 */
369			{
370				int field_selector = RANGE(3);
371				switch (field_selector) {
372				case 2:	/* field selector R`*/
373					printf(" R`");
374					break;
375				case 1:	/* field selector L`*/
376					printf(" L`");
377					break;
378				default:
379					break;
380				}
381				IMM_NUM(1048576);
382				continue;
383			}
384			case 'n':   /* nullification for branch instructions */
385				if (!do_not_nullify)
386					if (COIN)
387						printf(",n");
388				else
389					do_not_nullify = 0;
390				continue;
391			case 'w':   /* 12 bit branch displacement */
392				IMM_NUM(2048);
393				continue;
394			case 'W':   /* 17 bit branch displacement --- BL17 */
395			case '@':   /* 17 bit branch displacement --- JBSR */
396			case 'z':   /* 17 bit branch displacement (non-pc-relative) */
397				IMM_NUM(65536);
398				continue;
399			case 'B':   /* either "s,b" or "b" where b & s are defined above */
400				if (COIN)
401					printf(" %d,", RANGE(4));
402				printf(" %%r%d", RANGE(32));
403				break;
404			case 'A':   /* 13 bit immediate at 18 (to support BREAK instr.) */
405				printf(" %d", RANGE(4096));
406				continue;
407			case 'Z':   /* System Control Completer(for LDA, LHA, etc.) */
408				if (COIN)
409					printf(",M");
410  				continue;
411			case 'D':   /* 26 bit immediate at 31 (to support DIAG instr.) */
412  						/* the action (and interpretation of this operand is
413		 					implementation dependent) */
414				IMM_NUM(33554432);
415  				continue;
416			case 'f':   /* 3 bit Special Function Unit (SFU) identifier at 25 */
417			case 'u':   /* 3 bit coprocessor unit identifier at 25 */
418				printf("%d", RANGE(8));
419  				continue;
420			case 'O':   /* 20 bit SFU op. split between 15 bits at 20 and 5 bits at 31 */
421				printf("%d", RANGE(1048576));
422  				continue;
423			case 'o':   /* 15 bit Special Function Unit operation at 20 */
424			case '1':   /* 15 bit SFU op. split between 10 bits at 20
425			   				and 5 bits at 31 */
426				printf("%d", RANGE(32768));
427  				continue;
428			case '2':   /* 22 bit SFU op. split between 17 bits at 20
429			   				and 5 bits at 31 */
430				printf("%d", RANGE(4194304));
431  				continue;
432			case '0':   /* 10 bit SFU op. split between 5 bits at 20
433			   				and 5 bits at 31 */
434				printf("%d", RANGE(1024));
435  				continue;
436			case 'G':   /* Destination FP Operand Format Completer (2 bits at 18) */
437			case 'F':   /* Source FP Operand Format Completer (2 bits at 20) */
438				printf(",%s", fp_format_str[RANGE(NFPFMT)]);
439  				continue;
440			case 'M':   /* FP Compare Conditions (encoded as 5 bits at 31) */
441				printf(",%s", fp_cmp_cond[RANGE(NFPCOND)]);
442  				continue;
443
444#if 0
445			case 'H':  /* Floating Point Operand Format at 26 for       */
446						/* 'fmpyadd' and 'fmpysub' (very similar to 'F') */
447						/* bits are switched from other FP Operand       */
448						/* formats. 1=SGL, 1=<none>, 0=DBL               */
449				f = pa_parse_fp_format(&s);
450				switch (f) {
451				case SGL:
452					opcode |= 0x20;
453				case DBL:
454					the_insn.fpof1 = f;
455					continue;
456
457				case QUAD:
458				case ILLEGAL_FMT:
459				default:
460					as_bad("Illegal Floating Point Operand Format for"
461						"this instruction: '%s'",*s);
462				}
463				break;
464			default:
465				abort();
466#endif    /* 0 */
467
468			}
469		}
470		putchar( '\n' );
471	}
472	/* a label at the end of the file */
473	printf("label2:\n");
474
475
476	printf( "%s:\n", textlabels[3] );
477	printf( "\t.data\n" );
478	printf( "data1:	.space 1024\n" );
479	printf( "data2:	.space 1024\n" );
480	printf( "data3:	.space 1024\n" );
481	printf( "data4:	.space 1024\n" );
482
483}
484
485/* The function to search the condition decode table
486 * and return the 'cond'
487 * The way tables are initialised ... NULL termination
488 * of 'cond' is assured.
489 */
490char *get_cond_str(const condT table[8][2], int c, int f )
491{
492
493/* do range check and return NULL if out of bound */
494/*	char *str;
495	if ( c < 0  || c > 7 )
496		*str = (char *) NULL;
497	else	if ( f < 0  || f > 1 )
498		*str = (char *) NULL;
499	else
500		str = table[c][f].condition;
501
502	return str;
503*/
504
505/* here goes the one liner */
506
507	return (c<0 || c>7 || f<0 || f>1)
508		? (char *)NULL : table[c][f].condition	;
509}    /* end get_cond_str() */
510
511