home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OpenStep 4.2J (Developer)
/
os42jdev.iso
/
NextDeveloper
/
Source
/
GNU
/
cctools
/
as
/
hppa-check.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-20
|
13KB
|
511 lines
#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() */