snapshot, upper opcode table done, modulo testing

This commit is contained in:
Doug Evans
1998-01-14 20:13:07 +00:00
parent 3b542e9430
commit 3f89726318

View File

@ -57,7 +57,18 @@ PRINT_FN (dotdest);
PARSE_FN (vfreg); PARSE_FN (vfreg);
PRINT_FN (vfreg); PRINT_FN (vfreg);
/* Various types of ARC operands, including insn suffixes. PARSE_FN (bc);
PRINT_FN (bc);
PARSE_FN (ftregbc);
PRINT_FN (ftregbc);
PARSE_FN (accdest);
PRINT_FN (accdest);
PARSE_FN (xyz);
/* Various types of TXVU operands, including insn suffixes.
Fields are: Fields are:
@ -68,37 +79,95 @@ PRINT_FN (vfreg);
const struct txvu_operand txvu_operands[] = const struct txvu_operand txvu_operands[] =
{ {
/* place holder (??? not sure if needed) */ /* place holder (??? not sure if needed) */
#define UNUSED 128 #define UNUSED 128
{ 0 }, { 0 },
/* Destination indicator, with leading '.'. */ /* Destination indicator, with leading '.'. */
#define DOTDEST (UNUSED + 1) #define DOTDEST (UNUSED + 1)
{ 4, TXVU_SHIFT_DEST, TXVU_OPERAND_SUFFIX, { 4, TXVU_SHIFT_DEST, TXVU_OPERAND_SUFFIX,
parse_dotdest, insert_dotdest, extract_dotdest, print_dotdest }, parse_dotdest, insert_dotdest, extract_dotdest, print_dotdest },
/* ft reg */ /* ft reg */
#define FTREG (DOTDEST + 1) #define FTREG (DOTDEST + 1)
{ 5, TXVU_SHIFT_FTREG, 0, parse_vfreg, 0, 0, print_vfreg }, { 5, TXVU_SHIFT_FTREG, 0, parse_vfreg, 0, 0, print_vfreg },
/* fs reg */ /* fs reg */
#define FSREG (FTREG + 1) #define FSREG (FTREG + 1)
{ 5, TXVU_SHIFT_FSREG, 0, parse_vfreg, 0, 0, print_vfreg }, { 5, TXVU_SHIFT_FSREG, 0, parse_vfreg, 0, 0, print_vfreg },
/* fd reg */ /* fd reg */
#define FDREG (FSREG + 1) #define FDREG (FSREG + 1)
{ 5, TXVU_SHIFT_FDREG, 0, parse_vfreg, 0, 0, print_vfreg }, { 5, TXVU_SHIFT_FDREG, 0, parse_vfreg, 0, 0, print_vfreg },
/* broadcast */
#define BC (FDREG + 1)
{ 2, 0, 0, parse_bc, 0, 0, print_bc },
/* ftreg in broadcast case */
#define FTREGBC (BC + 1)
{ 5, TXVU_SHIFT_FTREG, 0, parse_ftregbc, 0, 0, print_ftregbc },
/* accumulator dest */
#define ACCDEST (FTREGBC + 1)
{ 0, 0, TXVU_OPERAND_FAKE, parse_accdest, 0, 0, print_accdest },
/* The XYZ operand is a fake one that is used to ensure only "xyz" is
specified. It simplifies the opmula and opmsub entries. */
#define XYZ (FDREG + 1)
{ 0, 0, TXVU_OPERAND_FAKE, parse_xyz, 0, 0, 0 },
/* end of list place holder */ /* end of list place holder */
{ 0 } { 0 }
}; };
/* Macros to put a field's value into the right place. */ /* Macros to put a field's value into the right place. */
#define FT(x) (((x) & TXVU_MASK_VFREG) << TXVU_SHIFT_FTREG) /* FIXME: If assembler needs these, move to opcode/txvu.h. */
#define FS(x) (((x) & TXVU_MASK_VFREG) << TXVU_SHIFT_FSREG)
#define FD(x) (((x) & TXVU_MASK_VFREG) << TXVU_SHIFT_FDREG)
#define R(x,b,m) (((x) & (m)) << (b)) /* value X, mask M, at bit B */ #define R(x,b,m) (((x) & (m)) << (b)) /* value X, mask M, at bit B */
/* Upper Flag bits. */
#define UF(x) R ((x), 27, 31)
/* Upper REServed two bits next to flag bits. */
#define URES(x) R ((x), 25, 3)
/* The DEST field. */
#define UDEST(x) R ((x), 21, 15)
/* The FT reg field. */
#define UFT(x) R ((x), TXVU_SHIFT_FTREG, TXVU_MASK_VFREG)
/* The FS reg field. */
#define UFS(x) R ((x), TXVU_SHIFT_FSREG, TXVU_MASK_VFREG)
/* The FD reg field. */
#define UFD(x) R ((x), TXVU_SHIFT_FDREG, TXVU_MASK_VFREG)
/* The 4 bit opcode field. */
#define UOP4(x) R ((x), 2, 15)
/* The 6 bit opcode field. */
#define UOP6(x) R ((x), 0, 63)
/* The 9 bit opcode field. */
#define UOP9(x) R ((x), 2, 0x1ff)
/* The 11 bit opcode field. */
#define UOP11(x) R ((x), 0, 0x7ff)
/* The BroadCast field. */
#define UBC(x) R ((x), 0, 3)
/* Macros for special field values. */
/* The upper 7 bits of the upper word. */
#define UUBITS (UF (0) + URES (0))
/* Mask for UBITS. */
#define MUUBITS (UF (~0) + URES (~0))
/* Mask for URES. */
#define MURES URES (~0)
/* Mask for OP4. */
#define MUOP4 UOP4 (~0)
/* Mask for OP6. */
#define MUOP6 UOP6 (~0)
/* Mask for OP9. */
#define MUOP9 UOP9 (~0)
/* Mask for OP11. */
#define MUOP11 UOP11 (~0)
/* A space, separates instruction name (mnemonic + mnemonic operands) from operands. */
#define SP ' '
/* TXVU instructions. /* TXVU instructions.
[??? some of these comments are left over from the ARC port from which [??? some of these comments are left over from the ARC port from which
this code is borrowed, delete in time] this code is borrowed, delete in time]
@ -128,10 +197,67 @@ struct txvu_opcode txvu_upper_opcodes[] = {
/* Macros appear first. */ /* Macros appear first. */
/* ??? Any aliases? */ /* ??? Any aliases? */
/* The rest of these needn't be sorted, but it helps to find them if they /* The rest of these needn't be sorted, but it helps to find them if they are. */
are. */ { "abs", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x1fd) },
{ "abs", { DOTDEST, ' ', FTREG, FSREG }, 0xfe0001ff, 0x1fd, 0 }, { "add", { DOTDEST, SP, FDREG, FSREG, FTREG }, MURES + MUOP6, UOP6 (0x28) },
{ "add", { DOTDEST, ' ', FDREG, FSREG, FTREG }, 0xfe00003f, 0x28, 0 }, { "addi", { DOTDEST, SP, FDREG, FSREG, 'i' }, MURES + UFT (~0) + MUOP6, UOP6 (0x22) },
{ "addq", { DOTDEST, SP, FDREG, FSREG, 'q' }, MURES + UFT (~0) + MUOP6, UOP6 (0x20) },
{ "add", { BC, DOTDEST, SP, FDREG, FSREG, FTREGBC }, MURES + UOP4 (~0), UOP4 (0) },
{ "adda", { DOTDEST, SP, ACCDEST, FSREG, FTREG }, MURES + MUOP11, UOP11 (0x2bc) },
{ "addai", { DOTDEST, SP, ACCDEST, FSREG, 'i' }, MURES + UFT (~0) + MUOP11, UOP11 (0x23e) },
{ "addaq", { DOTDEST, SP, ACCDEST, FSREG, 'q' }, MURES + UFT (~0) + MUOP11, UOP11 (0x23c) },
{ "adda", { BC, DOTDEST, SP, ACCDEST, FSREG, FTREGBC }, MURES + MUOP9, UOP9 (0xf) },
{ "clip", { DOTDEST, SP, FSREG }, MURES + UDEST (~0) + UFT (~0) + MUOP11, UDEST (0xf) + UOP11 (0x1ff) },
{ "ftoi0", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x17c) },
{ "ftoi4", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x17d) },
{ "ftoi12", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x17e) },
{ "ftoi15", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x17f) },
{ "itof0", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x13c) },
{ "itof4", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x13d) },
{ "itof12", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x13e) },
{ "itof15", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x13f) },
{ "madd", { DOTDEST, SP, FDREG, FSREG, FTREG }, MURES + MUOP6, UOP6 (0x29) },
{ "maddi", { DOTDEST, SP, FDREG, FSREG, 'i' }, MURES + UFT (~0) + MUOP6, UOP6 (0x23) },
{ "maddq", { DOTDEST, SP, FDREG, FSREG, 'q' }, MURES + UFT (~0) + MUOP6, UOP6 (0x21) },
{ "madd", { BC, DOTDEST, SP, FDREG, FSREG, FTREGBC }, MURES + MUOP4, UOP4 (0x2) },
{ "madda", { DOTDEST, SP, ACCDEST, FSREG, FTREG }, MURES + MUOP11, UOP11 (0x2bd) },
{ "maddai", { DOTDEST, SP, ACCDEST, FSREG, 'i' }, MURES + UFT (~0) + MUOP11, UOP11 (0x23f) },
{ "maddaq", { DOTDEST, SP, ACCDEST, FSREG, 'q' }, MURES + UFT (~0) + MUOP11, UOP11 (0x23d) },
{ "madda", { BC, DOTDEST, SP, ACCDEST, FSREG, FTREGBC }, MURES + MUOP9, UOP9 (0x2f) },
{ "max", { DOTDEST, SP, FDREG, FSREG, FTREG }, MURES + MUOP6, UOP6 (0x2b) },
{ "maxi", { DOTDEST, SP, FDREG, FSREG, 'i' }, MURES + UFT (~0) + MUOP6, UOP6 (0x2d) },
{ "max", { BC, DOTDEST, SP, FDREG, FSREG, FTREGBC }, MURES + MUOP4, UOP4 (0x4) },
/* FIXME: mini or min? */
{ "mini", { DOTDEST, SP, FDREG, FSREG, FTREG }, MURES + MUOP6, UOP6 (0x2f) },
{ "mini", { DOTDEST, SP, FDREG, FSREG, 'i' }, MURES + UFT (~0) + MUOP6, UOP6 (0x1f) },
{ "mini", { BC, DOTDEST, SP, FDREG, FSREG, FTREGBC }, MURES + MUOP4, UOP4 (0x5) },
{ "msub", { DOTDEST, SP, FDREG, FSREG, FTREG }, MURES + MUOP6, UOP6 (0x2d) },
{ "msubi", { DOTDEST, SP, FDREG, FSREG, 'i' }, MURES + UFT (~0) + MUOP6, UOP6 (0x27) },
{ "msubq", { DOTDEST, SP, FDREG, FSREG, 'q' }, MURES + UFT (~0) + MUOP6, UOP6 (0x25) },
{ "msub", { BC, DOTDEST, SP, FDREG, FSREG, FTREGBC }, MURES + MUOP4, UOP4 (0x3) },
{ "msuba", { DOTDEST, SP, ACCDEST, FSREG, FTREG }, MURES + MUOP11, UOP11 (0x2fd) },
{ "msubai", { DOTDEST, SP, ACCDEST, FSREG, 'i' }, MURES + UFT (~0) + MUOP11, UOP11 (0x27f) },
{ "msubaq", { DOTDEST, SP, ACCDEST, FSREG, 'q' }, MURES + UFT (~0) + MUOP11, UOP11 (0x27d) },
{ "msuba", { BC, DOTDEST, SP, ACCDEST, FSREG, FTREGBC }, MURES + MUOP9, UOP9 (0x3f) },
{ "mul", { DOTDEST, SP, FDREG, FSREG, FTREG }, MURES + MUOP6, UOP6 (0x2a) },
{ "muli", { DOTDEST, SP, FDREG, FSREG, 'i' }, MURES + UFT (~0) + MUOP6, UOP6 (0x1e) },
{ "mulq", { DOTDEST, SP, FDREG, FSREG, 'q' }, MURES + UFT (~0) + MUOP6, UOP6 (0x1c) },
{ "mul", { BC, DOTDEST, SP, FDREG, FSREG, FTREGBC }, MURES + UOP4 (~0), UOP4 (6) },
{ "mula", { DOTDEST, SP, ACCDEST, FSREG, FTREG }, MURES + MUOP11, UOP11 (0x2be) },
{ "mulai", { DOTDEST, SP, ACCDEST, FSREG, 'i' }, MURES + UFT (~0) + MUOP11, UOP11 (0x1fe) },
{ "mulaq", { DOTDEST, SP, ACCDEST, FSREG, 'q' }, MURES + UFT (~0) + MUOP11, UOP11 (0x1fc) },
{ "mula", { BC, DOTDEST, SP, ACCDEST, FSREG, FTREGBC }, MURES + MUOP9, UOP9 (0x6f) },
{ "nop", { 0 }, MURES + UDEST (~0) + UFT (~0) + UFS (~0) + MUOP11, UOP11 (0x2ff) },
{ "opmula", { DOTDEST, SP, ACCDEST, FSREG, FTREG, XYZ }, MURES + MUOP11, UOP11 (0x2fe) },
{ "opmsub", { DOTDEST, SP, FDREG, FSREG, FTREG, XYZ }, MURES + MUOP6, UOP6 (0x2e) },
{ "sub", { DOTDEST, SP, FDREG, FSREG, FTREG }, MURES + MUOP6, UOP6 (0x2c) },
{ "subi", { DOTDEST, SP, FDREG, FSREG, 'i' }, MURES + UFT (~0) + MUOP6, UOP6 (0x26) },
{ "subq", { DOTDEST, SP, FDREG, FSREG, 'q' }, MURES + UFT (~0) + MUOP6, UOP6 (0x24) },
{ "sub", { BC, DOTDEST, SP, FDREG, FSREG, FTREGBC }, MURES + UOP4 (~0), UOP4 (1) },
{ "suba", { DOTDEST, SP, ACCDEST, FSREG, FTREG }, MURES + MUOP11, UOP11 (0x2fc) },
{ "subai", { DOTDEST, SP, ACCDEST, FSREG, 'i' }, MURES + UFT (~0) + MUOP11, UOP11 (0x27e) },
{ "subaq", { DOTDEST, SP, ACCDEST, FSREG, 'q' }, MURES + UFT (~0) + MUOP11, UOP11 (0x27c) },
{ "suba", { BC, DOTDEST, SP, ACCDEST, FSREG, FTREGBC }, MURES + MUOP9, UOP9 (0x1f) }
}; };
const int txvu_upper_opcodes_count = sizeof (txvu_upper_opcodes) / sizeof (txvu_opcodes[0]); const int txvu_upper_opcodes_count = sizeof (txvu_upper_opcodes) / sizeof (txvu_opcodes[0]);
@ -253,6 +379,11 @@ txvu_lower_opcode_lookup_dis (insn)
Each of the registers must specify the same value as the opcode. Each of the registers must specify the same value as the opcode.
??? Perhaps remove the duplication? */ ??? Perhaps remove the duplication? */
static int dest; static int dest;
/* Value of BC to use.
The register specified for the ftreg must match the broadcast register
specified in the opcode. */
static int bc;
/* Init fns. /* Init fns.
These are called before doing each of the respective activities. */ These are called before doing each of the respective activities. */
@ -263,6 +394,7 @@ void
txvu_opcode_init_parse () txvu_opcode_init_parse ()
{ {
dest = -1; dest = -1;
bc = -1;
} }
/* Called by the disassembler before printing an instruction. */ /* Called by the disassembler before printing an instruction. */
@ -271,6 +403,7 @@ void
txvu_opcode_init_print () txvu_opcode_init_print ()
{ {
dest = -1; dest = -1;
bc = -1;
} }
/* Destination choice support. /* Destination choice support.
@ -428,3 +561,152 @@ print_vfreg (info, insn, value)
(*info->fprintf_func) (info->stream, "vf%ld", value); (*info->fprintf_func) (info->stream, "vf%ld", value);
print_dest (info, insn, dest); print_dest (info, insn, dest);
} }
/* Broadcast handling. */
static long
parse_bc (pstr, errmsg)
char **pstr;
const char **errmsg;
{
long dest = 0;
switch (**pstr)
{
case 'x' : case 'X' : dest = TXVU_BC_X; break;
case 'y' : case 'Y' : dest = TXVU_BC_Y; break;
case 'z' : case 'Z' : dest = TXVU_BC_Z; break;
case 'w' : case 'W' : dest = TXVU_BC_W; break;
default : *errmsg = "invalid `bc'"; return 0;
}
++*pstr;
*errmsg = NULL;
return dest;
}
static void
print_bc (info, insn, value)
disassemble_info *info;
TXVU_INSN insn;
long value;
{
char c;
switch (value)
{
case TXVU_BC_X : c = 'x' ; break;
case TXVU_BC_Y : c = 'y' ; break;
case TXVU_BC_Z : c = 'z' ; break;
case TXVU_BC_W : c = 'w' ; break;
}
(*info->fprintf_func) (info->stream, "%c", c);
}
/* FT register in broadcast case. */
static long
parse_ftregbc (pstr, errmsg)
char **pstr;
const char **errmsg;
{
char *str = *pstr;
char *start;
long reg;
int reg_bc;
if (tolower (str[0]) != 'v'
|| tolower (str[1]) != 'f')
{
*errmsg = "unknown register";
return 0;
}
/* FIXME: quick hack until the framework works. */
start = str = str + 2;
while (*str && isdigit (*str))
++str;
reg = atoi (start);
reg_bc = parse_bc (&str, errmsg);
if (*errmsg)
return 0;
if (reg_bc != bc)
{
*errmsg = "register `bc' does not match instruction `bc'";
return 0;
}
*pstr = str;
*errmsg = NULL;
return reg;
}
static void
print_ftregbc (info, insn, value)
disassemble_info *info;
TXVU_INSN insn;
long value;
{
(*info->fprintf_func) (info->stream, "vf%ld", value);
print_bc (info, insn, bc);
}
/* ACC handling. */
static long
parse_accdest (pstr, errmsg)
char **pstr;
const char **errmsg;
{
char *str = *pstr;
long acc_dest = 0;
if (strncasecmp (str, "acc", 3) != 0)
{
*errmsg = "expecting `acc'";
return 0;
}
str += 3;
acc_dest = parse_dest (&str);
if (acc_dest == 0 || isalnum (*str))
{
*errmsg = "invalid `dest'";
return 0;
}
if (acc_dest != dest)
{
*errmsg = "acc `dest' does not match instruction `dest'";
return 0;
}
*pstr = str;
*errmsg = NULL;
/* Value isn't used, but we must return something. */
return 0;
}
static void
print_accdest (info, insn, value)
disassemble_info *info;
TXVU_INSN insn;
long value;
{
(*info->fprintf_func) (info->stream, "acc");
print_dest (info, insn, value);
}
/* XYZ operand handling.
This simplifies the opmula,opmsub entries by keeping them equivalent to
the others. */
static long
parse_xyz (pstr, errmsg)
char **pstr;
const char **errmsg;
{
if (dest != (TXVU_DEST_X | TXVU_DEST_Y | TXVU_DEST_Z))
{
*errmsg = "expecting `xyz' for `dest' value";
return 0;
}
return 0;
}