|
|
1.1 root 1: #include "hppa-opcode.h"
2: #include <stdio.h>
3:
4: extern long 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:
19: typedef struct condition_decode {
20: char condition[4];
21: } condT;
22:
23: char *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 */
36: const 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 */
48: const 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 */
60: const 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 */
72: const 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 */
84: const 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:
97: char *controlregs[] = { "fir", "psr", "epsr", "dirbase", "db", "fsr" };
98: #define NCREGS (sizeof controlregs / sizeof controlregs[0])
99:
100: char *textlabels[] = { "foo", "bar", "baz", "xork" };
101: #define NTLABELS (sizeof textlabels / sizeof textlabels[0])
102:
103: char *datalabels[] = { "data1", "data2", "data3", "data4" };
104: #define NDLABELS (sizeof datalabels / sizeof datalabels[0])
105:
106: char *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:
114: char *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: */
120: void
121: main()
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: */
490: char *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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.