This is hppa-check.c in view mode; [Download] [Up]
#include "hppa-opcode.h" #include <stdio.h> extern long random(); #define RANGE(number) (random() % (number)) #define COIN (RANGE(2)) #define IMM_NUM(range) { int tmp000111000usv = RANGE(range); \ if (tmp000111000usv == 0) \ printf(" %d", tmp000111000usv); \ else \ printf(" %c%d", (COIN) ? '-' : ' ', \ tmp000111000usv); \ } /* The 'cond' decode table */ typedef struct condition_decode { char condition[4]; } condT; char *get_cond_str(const condT table[8][2], int c, int f ); /* condition decode tables * Refer to PA-RISC 1.1 Architecture and Instruction Set * Reference Manual, Second edition, Sep. 1992, pp. 5-2 - 5-8. */ /* Note : In all the following tables * "" ... never * "???" ... Invalid combination */ /* compare/subtraclt instruction conditions */ const condT c_comp_sub[8][2] = { /* Table 5-3 */ { "", "TR" }, { "=", "<>" }, { "<", ">=" }, { "<=", ">" }, { "<<", ">>=" }, { "<<=", ">>" }, { "SV", "NSV" }, { "OD", "EV" } }; /* add instruction conditions */ const condT c_add[8][2] = { /* Table 5-4 */ { "", "TR" }, { "=", "<>" }, { "<", ">=" }, { "<=", ">" }, { "NUV", "UV" }, { "ZNV", "VNZ" }, { "SV", "NSV" }, { "OD", "EV" } }; /* logical instruction conditions */ const condT c_logical[8][2] = { /* Table 5-5 */ { "", "TR" }, { "=", "<>" }, { "<", ">=" }, { "<=", ">" }, { "???", "???" }, { "???", "???" }, { "???", "???" }, { "OD", "EV" } }; /* unit instruction conditions */ const condT c_unit[8][2] = { /* Table 5-6 */ { "", "TR" }, { "???", "???" }, { "SBZ", "NBZ" }, { "SHZ", "NHZ" }, { "SDC", "NDC" }, { "???", "???" }, { "SBC", "NBC" }, { "SHC", "NHC" } }; /* shift/extract/deposit instruction conditions */ const condT c_shift_extract_deposit[8][2] = { /* Table 5-7 */ { "", "???" }, { "=", "???" }, { "<", "???" }, { "OD", "???" }, { "TR", "???" }, { "<>", "???" }, { ">=", "???" }, { "EV", "???" } }; char *controlregs[] = { "fir", "psr", "epsr", "dirbase", "db", "fsr" }; #define NCREGS (sizeof controlregs / sizeof controlregs[0]) char *textlabels[] = { "foo", "bar", "baz", "xork" }; #define NTLABELS (sizeof textlabels / sizeof textlabels[0]) char *datalabels[] = { "data1", "data2", "data3", "data4" }; #define NDLABELS (sizeof datalabels / sizeof datalabels[0]) char *fp_cmp_cond[] = { "false?","false", "true?", "true", "!<=>", "!?>=", "!?<=", "!<>", "!>=", "!?>", "?<=", "!<=", "!?<", "?>=", "!?=", "!=t", "<=>", "=t", "?=", "?<", "<=", "!>", "?>", ">=", "!<", "<>", "!=", "!?", "?", "=", "<", ">" }; #define NFPCOND (sizeof fp_cmp_cond / sizeof fp_cmp_cond[0]) char *fp_format_str[] = { "sgl", "dbl", "quad" }; #define NFPFMT (sizeof fp_format_str / sizeof fp_format_str[0]) /* * Traverse the opcode table, dumping out sample instructions. */ void main() { int i; const char *arg; int do_not_nullify = 0; printf( "\t.text\n%s:", textlabels[0] ); /* a label at the begining of the file */ printf("label1:\n"); for ( i = 0; i < NUMOPCODES; ++i ) { if ( i == (NUMOPCODES/3) ) printf( "%s:", textlabels[1] ); if ( i == (NUMOPCODES/2) ) printf( "%s:", textlabels[2] ); printf( "\t%s", pa_opcodes[i].name ); for ( arg = pa_opcodes[i].args; *arg != '\0'; ++arg ) { switch( *arg ) { case '\0': /* end of args */ break; case '(': /* these must match exactly */ putchar(' '); /* and FALLTHRU */ case ')': case ',': case ' ': putchar(*arg); break; case 'b': /* 5 bit register field at 10 */ case 'x': /* 5 bit register field at 15 */ case 't': /* 5 bit register field at 31 */ case 'v': /* a 't' type extended to handle L/R register halves. */ case 'E': /* a 'b' type extended to handle L/R register halves. */ case 'X': /* an 'x' type extended to handle L/R register halves. */ case '4': /* 5 bit register field at 10 (used in 'fmpyadd' and 'fmpysub') */ case '6': /* 5 bit register field at 15 (used in 'fmpyadd' and 'fmpysub') */ case '7': /* 5 bit register field at 31 (used in 'fmpyadd' and 'fmpysub') */ case '8': /* 5 bit register field at 20 (used in 'fmpyadd' and 'fmpysub') */ case '9': /* 5 bit register field at 25 (used in 'fmpyadd' and 'fmpysub') */ printf(" %%r%d", RANGE(32)); break; case 'r': /* 5 bit immediate at 31 */ case 'R': /* 5 bit immediate at 15 */ printf(" %d", RANGE(32)); break; case 'T': /* 5 bit field length at 31 (encoded as 32-T) */ printf(" %d", RANGE(31) + 1); break; case '5': /* 5 bit immediate at 15 */ case 'V': /* 5 bit immediate at 31 */ case 'p': /* 5 bit shift count at 26 (to support SHD instr.) */ /* value is encoded in instr. as 31-p where p is */ /* the value scanned here */ case 'P': /* 5-bit bit position at 26 */ case 'Q': /* 5 bit immediate at 10 (unsigned bit position */ /* value for the bb instruction) */ IMM_NUM(15); continue; case 's': /* 2 bit space identifier at 17 */ printf(" %d", RANGE(4)); break; case 'S': /* 3 bit space identifier at 18 */ printf(" %%sr%d", RANGE(8)); break; case 'c': /* indexed load completer. */ { int m, u, i; m = COIN; u = COIN; i = 0; if (COIN) while (i < 2) { if (m==1 && u==1) { printf(",sm"); i++; } else if (m==1) printf(",m"); else if (u==1) printf(",s"); else /* m==0 && u==0 */ { printf(",sm"); i++; } /* probability distribution */ i++; } continue; } case 'C': /* short load and store completer */ if (COIN) if (COIN) printf(",mb"); else printf(",ma"); continue; case 'Y': /* Store Bytes Short completer */ { int i = 0, m, a; while ( i < 2 ) { m = COIN; a = COIN; if (m==1) /* && (a==0 || a==1) */ printf(",m"); else if (a==0) /* && m==0 */ printf(",b"); else if (a==1) /* && m==0 */ printf(",e"); i++; } continue; } case '<': /* non-negated compare/subtract conditions. */ { int cmpltr; do { cmpltr = RANGE(4); } while (cmpltr == 0); printf(",%s", get_cond_str(c_comp_sub, cmpltr, 0)); } continue; case '?': /* negated or non-negated cmp/sub conditions. */ /* used only by ``comb'' and ``comib'' pseudo-ops */ case '-': /* compare/subtract conditions */ { int flag, cmpltr; char *tmp; do { flag = COIN; cmpltr = RANGE(8); } while ((flag & cmpltr) == 0 || (cmpltr == 0)); tmp = get_cond_str(c_comp_sub, cmpltr, flag); if (*tmp != '\0') printf(",%s", tmp); } continue; case '+': /* non-negated add conditions */ case '!': /* negated or non-negated add conditions. */ { int flag, cmpltr; char *tmp; do { flag = COIN; cmpltr = RANGE(8); } while ((flag & cmpltr) == 0 || (cmpltr == 0)); tmp = get_cond_str(c_add, cmpltr, flag); if (COIN && (*tmp != '\0')) /* condition */ { printf(",%s", tmp); if (COIN) { /* nullify */ printf(",n "); do_not_nullify = 1; } } } continue; case '&': /* logical instruction conditions */ { int flag, cmpltr; char *tmp; flag = COIN; do { cmpltr = RANGE(8); } while (cmpltr == 4 || cmpltr == 5 || cmpltr == 6); tmp = get_cond_str(c_logical, cmpltr, flag); if (COIN && (*tmp != '\0')) /* condition */ printf(",%s", tmp); } continue; case 'U': /* unit instruction conditions */ { int flag, cmpltr; char *tmp; flag = COIN; do { cmpltr = RANGE(8); } while (cmpltr == 1 || cmpltr == 5); tmp = get_cond_str(c_unit, cmpltr, flag); if (COIN && (*tmp != '\0')) /* condition */ printf(",%s", tmp); } continue; case '>': /* shift/extract/deposit conditions. */ { int cmpltr; char *tmp; cmpltr = RANGE(8); tmp = get_cond_str(c_shift_extract_deposit, cmpltr, 0); if (COIN && (*tmp != '\0')) /* condition */ printf(",%s", tmp); } continue; case '~': /* bvb,bb conditions */ if (COIN) printf(",<"); else printf(",>="); continue; case 'i': /* 11 bit immediate at 31 */ IMM_NUM(1024); continue; case 'j': /* 14 bit immediate at 31 --- LO14 */ case 'a': /* for be, ble --- BR17*/ { int field_selector = RANGE(3); switch (field_selector) { case 2: /* field selector R`*/ printf(" R`"); break; case 1: /* field selector L`*/ printf(" L`"); break; default: break; } IMM_NUM(8192); continue; } case 'k': /* 21 bit immediate at 31 --- HI21 */ { int field_selector = RANGE(3); switch (field_selector) { case 2: /* field selector R`*/ printf(" R`"); break; case 1: /* field selector L`*/ printf(" L`"); break; default: break; } IMM_NUM(1048576); continue; } case 'n': /* nullification for branch instructions */ if (!do_not_nullify) if (COIN) printf(",n"); else do_not_nullify = 0; continue; case 'w': /* 12 bit branch displacement */ IMM_NUM(2048); continue; case 'W': /* 17 bit branch displacement --- BL17 */ case '@': /* 17 bit branch displacement --- JBSR */ case 'z': /* 17 bit branch displacement (non-pc-relative) */ IMM_NUM(65536); continue; case 'B': /* either "s,b" or "b" where b & s are defined above */ if (COIN) printf(" %d,", RANGE(4)); printf(" %%r%d", RANGE(32)); break; case 'A': /* 13 bit immediate at 18 (to support BREAK instr.) */ printf(" %d", RANGE(4096)); continue; case 'Z': /* System Control Completer(for LDA, LHA, etc.) */ if (COIN) printf(",M"); continue; case 'D': /* 26 bit immediate at 31 (to support DIAG instr.) */ /* the action (and interpretation of this operand is implementation dependent) */ IMM_NUM(33554432); continue; case 'f': /* 3 bit Special Function Unit (SFU) identifier at 25 */ case 'u': /* 3 bit coprocessor unit identifier at 25 */ printf("%d", RANGE(8)); continue; case 'O': /* 20 bit SFU op. split between 15 bits at 20 and 5 bits at 31 */ printf("%d", RANGE(1048576)); continue; case 'o': /* 15 bit Special Function Unit operation at 20 */ case '1': /* 15 bit SFU op. split between 10 bits at 20 and 5 bits at 31 */ printf("%d", RANGE(32768)); continue; case '2': /* 22 bit SFU op. split between 17 bits at 20 and 5 bits at 31 */ printf("%d", RANGE(4194304)); continue; case '0': /* 10 bit SFU op. split between 5 bits at 20 and 5 bits at 31 */ printf("%d", RANGE(1024)); continue; case 'G': /* Destination FP Operand Format Completer (2 bits at 18) */ case 'F': /* Source FP Operand Format Completer (2 bits at 20) */ printf(",%s", fp_format_str[RANGE(NFPFMT)]); continue; case 'M': /* FP Compare Conditions (encoded as 5 bits at 31) */ printf(",%s", fp_cmp_cond[RANGE(NFPCOND)]); continue; #if 0 case 'H': /* Floating Point Operand Format at 26 for */ /* 'fmpyadd' and 'fmpysub' (very similar to 'F') */ /* bits are switched from other FP Operand */ /* formats. 1=SGL, 1=<none>, 0=DBL */ f = pa_parse_fp_format(&s); switch (f) { case SGL: opcode |= 0x20; case DBL: the_insn.fpof1 = f; continue; case QUAD: case ILLEGAL_FMT: default: as_bad("Illegal Floating Point Operand Format for" "this instruction: '%s'",*s); } break; default: abort(); #endif /* 0 */ } } putchar( '\n' ); } /* a label at the end of the file */ printf("label2:\n"); printf( "%s:\n", textlabels[3] ); printf( "\t.data\n" ); printf( "data1: .space 1024\n" ); printf( "data2: .space 1024\n" ); printf( "data3: .space 1024\n" ); printf( "data4: .space 1024\n" ); } /* The function to search the condition decode table * and return the 'cond' * The way tables are initialised ... NULL termination * of 'cond' is assured. */ char *get_cond_str(const condT table[8][2], int c, int f ) { /* do range check and return NULL if out of bound */ /* char *str; if ( c < 0 || c > 7 ) *str = (char *) NULL; else if ( f < 0 || f > 1 ) *str = (char *) NULL; else str = table[c][f].condition; return str; */ /* here goes the one liner */ return (c<0 || c>7 || f<0 || f>1) ? (char *)NULL : table[c][f].condition ; } /* end get_cond_str() */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.