static long CONCAT2 (parse_,fn) \
PARAMS ((char **, const char **));
#define INSERT_FN(fn) \
-static TXVU_INSN CONCAT2 (insert_,fn) \
- PARAMS ((TXVU_INSN, const struct txvu_operand *, \
+static void CONCAT2 (insert_,fn) \
+ PARAMS ((TXVU_INSN *, const struct txvu_operand *, \
int, long, const char **))
#define EXTRACT_FN(fn) \
static long CONCAT2 (extract_,fn) \
- PARAMS ((TXVU_INSN, const struct txvu_operand *, \
+ PARAMS ((TXVU_INSN *, const struct txvu_operand *, \
int, int *))
#define PRINT_FN(fn) \
static void CONCAT2 (print_,fn) \
- PARAMS ((disassemble_info *, TXVU_INSN, long));
+ PARAMS ((disassemble_info *, TXVU_INSN *, long));
PARSE_FN (dotdest);
INSERT_FN (dotdest);
};
const int txvu_lower_opcodes_count = sizeof (txvu_lower_opcodes) / sizeof (txvu_lower_opcodes[0]);
\f
-/* Indexed by first letter of opcode. Points to chain of opcodes with same
- first letter. */
-/* ??? One can certainly use a better hash. Later. */
-static struct txvu_opcode *upper_opcode_map[26 + 1];
-static struct txvu_opcode *lower_opcode_map[26 + 1];
-
-/* Indexed by insn code. Points to chain of opcodes with same insn code. */
-static struct txvu_opcode *upper_icode_map[(1 << TXVU_ICODE_HASH_SIZE) - 1];
-static struct txvu_opcode *lower_icode_map[(1 << TXVU_ICODE_HASH_SIZE) - 1];
-\f
-/* Initialize any tables that need it.
- Must be called once at start up (or when first needed).
-
- FLAGS is currently unused but is intended to control initialization. */
-
-void
-txvu_opcode_init_tables (flags)
- int flags;
-{
- static int init_p = 0;
-
- /* We may be intentionally called more than once (for example gdb will call
- us each time the user switches cpu). These tables only need to be init'd
- once though. */
- /* ??? We can remove the need for txvu_opcode_supported by taking it into
- account here, but I'm not sure I want to do that yet (if ever). */
- if (!init_p)
- {
- int i,n;
-
- memset (upper_opcode_map, 0, sizeof (upper_opcode_map));
- memset (upper_icode_map, 0, sizeof (upper_icode_map));
-
- /* Scan the table backwards so macros appear at the front. */
- for (i = txvu_upper_opcodes_count - 1; i >= 0; --i)
- {
- int opcode_hash = TXVU_HASH_UPPER_OPCODE (txvu_upper_opcodes[i].mnemonic);
- int icode_hash = TXVU_HASH_UPPER_ICODE (txvu_upper_opcodes[i].value);
-
- txvu_upper_opcodes[i].next_asm = upper_opcode_map[opcode_hash];
- upper_opcode_map[opcode_hash] = &txvu_upper_opcodes[i];
-
- txvu_upper_opcodes[i].next_dis = upper_icode_map[icode_hash];
- upper_icode_map[icode_hash] = &txvu_upper_opcodes[i];
- }
-
- memset (lower_opcode_map, 0, sizeof (lower_opcode_map));
- memset (lower_icode_map, 0, sizeof (lower_icode_map));
-
- /* Scan the table backwards so macros appear at the front. */
- for (i = txvu_lower_opcodes_count - 1; i >= 0; --i)
- {
- int opcode_hash = TXVU_HASH_LOWER_OPCODE (txvu_lower_opcodes[i].mnemonic);
- int icode_hash = TXVU_HASH_LOWER_ICODE (txvu_lower_opcodes[i].value);
-
- txvu_lower_opcodes[i].next_asm = lower_opcode_map[opcode_hash];
- lower_opcode_map[opcode_hash] = &txvu_lower_opcodes[i];
-
- txvu_lower_opcodes[i].next_dis = lower_icode_map[icode_hash];
- lower_icode_map[icode_hash] = &txvu_lower_opcodes[i];
- }
-
- init_p = 1;
- }
-}
-
-/* Return the first insn in the chain for assembling upper INSN. */
-
-const struct txvu_opcode *
-txvu_upper_opcode_lookup_asm (insn)
- const char *insn;
-{
- return upper_opcode_map[TXVU_HASH_UPPER_OPCODE (insn)];
-}
-
-/* Return the first insn in the chain for assembling lower INSN. */
-
-const struct txvu_opcode *
-txvu_lower_opcode_lookup_asm (insn)
- const char *insn;
-{
- return lower_opcode_map[TXVU_HASH_LOWER_OPCODE (insn)];
-}
-
-/* Return the first insn in the chain for disassembling upper INSN. */
-
-const struct txvu_opcode *
-txvu_upper_opcode_lookup_dis (insn)
- TXVU_INSN insn;
-{
- return upper_icode_map[TXVU_HASH_UPPER_ICODE (insn)];
-}
-
-/* Return the first insn in the chain for disassembling lower INSN. */
-
-const struct txvu_opcode *
-txvu_lower_opcode_lookup_dis (insn)
- TXVU_INSN insn;
-{
- return lower_icode_map[TXVU_HASH_LOWER_ICODE (insn)];
-}
-\f
/* Value of DEST in use.
Each of the registers must specify the same value as the opcode.
??? Perhaps remove the duplication? */
specified in the opcode. */
static int mnemonic_bc;
\f
-/* Init fns.
- These are called before doing each of the respective activities. */
-
-/* Called by the assembler before parsing an instruction. */
-
-void
-txvu_opcode_init_parse ()
-{
- mnemonic_dest = -1;
- mnemonic_bc = -1;
-}
-
-/* Called by the disassembler before printing an instruction. */
-
-void
-txvu_opcode_init_print ()
-{
- mnemonic_dest = -1;
- mnemonic_bc = -1;
-}
-\f
/* Multiple destination choice support.
The "dest" string selects any combination of x,y,z,w.
[The letters are ordered that way to follow the manual's style.] */
return 0;
}
- *errmsg = NULL;
return dest;
}
return 0;
}
- *errmsg = NULL;
return dest;
}
return 0;
}
- *errmsg = NULL;
return dest;
}
-static TXVU_INSN
+static void
insert_dotdest (insn, operand, mods, value, errmsg)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
long value;
{
/* Record the DEST value in use so the register parser can use it. */
mnemonic_dest = value;
- return insn |= value << operand->shift;
+ *insn |= value << operand->shift;
}
static long
extract_dotdest (insn, operand, mods, pinvalid)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
int *pinvalid;
{
/* Record the DEST value in use so the register printer can use it. */
- mnemonic_dest = (insn >> operand->shift) & ((1 << operand->bits) - 1);
+ mnemonic_dest = (*insn >> operand->shift) & ((1 << operand->bits) - 1);
return mnemonic_dest;
}
static void
_print_dest (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
if (value & TXVU_DEST_X)
static void
print_dotdest (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, ".");
static void
print_dest1 (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
_print_dest (info, insn, mnemonic_dest);
return 0;
}
- *errmsg = NULL;
return dest;
}
static void
print_sdest (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
char c;
static long
extract_bc (insn, operand, mods, pinvalid)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
int *pinvalid;
{
- mnemonic_bc = insn & 3;
+ mnemonic_bc = *insn & 3;
return mnemonic_bc;
}
\f
return 0;
}
*pstr = str;
- *errmsg = NULL;
return reg;
}
static void
print_vfreg (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "vf%02ld", value);
return 0;
}
*pstr = str;
- *errmsg = NULL;
return reg;
}
static void
print_bcftreg (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "vf%02ld", value);
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;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "acc");
This simplifies the opmula,opmsub entries by keeping them equivalent to
the others. */
-static TXVU_INSN
+static void
insert_xyz (insn, operand, mods, value, errmsg)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
long value;
const char **errmsg;
{
if (mnemonic_dest != (TXVU_DEST_X | TXVU_DEST_Y | TXVU_DEST_Z))
- {
- *errmsg = "expecting `xyz' for `dest' value";
- return insn;
- }
- return insn;
+ *errmsg = "expecting `xyz' for `dest' value";
}
\f
/* F[ST] register using selector in F[ST]F field.
if (*errmsg)
return 0;
*pstr = str;
- *errmsg = NULL;
return reg | (xyzw << 5);
}
static void
print_ffstreg (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "vf%02ld", value & TXVU_MASK_REG);
print_sdest (info, insn, (value >> 5) & 3);
}
-static TXVU_INSN
+static void
insert_ffstreg (insn, operand, mods, value, errmsg)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
long value;
const char **errmsg;
{
if (operand->shift == TXVU_SHIFT_SREG)
- return insn | VLFSF (value >> 5) | VS (value);
+ *insn |= VLFSF (value >> 5) | VS (value);
else
- return insn | VLFTF (value >> 5) | VT (value);
+ *insn |= VLFTF (value >> 5) | VT (value);
}
static long
extract_ffstreg (insn, operand, mods, pinvalid)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
int *pinvalid;
{
if (operand->shift == TXVU_SHIFT_SREG)
- return (((insn & VLFSF (~0)) >> 21) << 5) | VS (insn);
+ return (((*insn & VLFSF (~0)) >> 21) << 5) | VS (*insn);
else
- return (((insn & VLFTF (~0)) >> 21) << 5) | VT (insn);
+ return (((*insn & VLFTF (~0)) >> 21) << 5) | VT (*insn);
}
\f
/* F register. */
return 0;
}
*pstr = str;
- *errmsg = NULL;
return reg;
}
static void
print_freg (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "vf%02ld", value);
return 0;
}
*pstr = str;
- *errmsg = NULL;
return reg;
}
static void
print_ireg (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "vi%02ld", value);
return 0;
}
*pstr = str;
- *errmsg = NULL;
return reg;
}
static void
print_vi01 (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "vi01");
\f
/* Lower instruction 12 bit unsigned immediate. */
-static TXVU_INSN
+static void
insert_luimm12 (insn, operand, mods, value, errmsg)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
long value;
const char **errmsg;
{
- return insn | VLUIMM12TOP ((value & (1 << 11)) != 0) | VLIMM11 (value);
+ *insn |= VLUIMM12TOP ((value & (1 << 11)) != 0) | VLIMM11 (value);
}
static long
extract_luimm12 (insn, operand, mods, pinvalid)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
int *pinvalid;
{
- return (((insn & MLUIMM12TOP) != 0) << 11) | VLIMM11 (insn);
+ return (((*insn & MLUIMM12TOP) != 0) << 11) | VLIMM11 (*insn);
}
/* Lower instruction 12 bit unsigned immediate, upper 6 bits. */
-static TXVU_INSN
+static void
insert_luimm12up6 (insn, operand, mods, value, errmsg)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
long value;
const char **errmsg;
{
- return insn | VLUIMM12TOP ((value & (1 << 11)) != 0) | (value & 0x7c0);
+ *insn |= VLUIMM12TOP ((value & (1 << 11)) != 0) | (value & 0x7c0);
}
\f
/* Lower instruction 15 bit unsigned immediate. */
-static TXVU_INSN
+static void
insert_luimm15 (insn, operand, mods, value, errmsg)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
long value;
const char **errmsg;
{
- return insn | VLUIMM15TOP (value >> 11) | VLIMM11 (value);
+ *insn |= VLUIMM15TOP (value >> 11) | VLIMM11 (value);
}
static long
extract_luimm15 (insn, operand, mods, pinvalid)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
int *pinvalid;
{
- return (((insn & MLUIMM15TOP) >> 21) << 11) | VLIMM11 (insn);
+ return (((*insn & MLUIMM15TOP) >> 21) << 11) | VLIMM11 (*insn);
}
\f
/* PKE support. */
PARSE_FN (pke_unpackaddr);
-const struct txvu_operand txvu_pke_operands[] =
+const struct txvu_operand pke_operands[] =
{
/* place holder (??? not sure if needed) */
#define PKE_UNUSED 128
#define VPKECMD(x) V ((x), 7, 24)
#define VPKEUNPACK V (0x60, 8, 24)
-struct txvu_opcode txvu_pke_opcodes[] =
+struct txvu_opcode pke_opcodes[] =
{
{ "pkenop", { PKE_IBIT }, 0x7fffffff, 0 },
{ "stcycle", { PKE_IBIT, SP, PKE_UIMM8UP, C, PKE_UIMM8LO }, MPKECMD, VPKECMD (1) },
{ "directhl", { PKE_IBIT, SP, PKE_VARLENDATA }, MPKECMD, VPKECMD (0x51), PKE_OPCODE_LENVAR + PKE_OPCODE_DIRECT },
{ "unpack", { PKE_IMRBITS, SP, PKE_UNPACKTYPE, C, PKE_UNPACKADDR, C, PKE_VARLENDATA }, MPKEUNPACK, VPKEUNPACK, PKE_OPCODE_LENVAR + PKE_OPCODE_UNPACK },
};
-const int txvu_pke_opcodes_count = sizeof (txvu_pke_opcodes) / sizeof (txvu_pke_opcodes[0]);
+const int pke_opcodes_count = sizeof (pke_opcodes) / sizeof (pke_opcodes[0]);
\f
/* PKE parse,insert,extract,print helper fns. */
static void
print_pke_ibit (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "???");
static void
print_pke_mode (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "???");
static void
print_pke_ability (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "???");
static void
print_pke_imrbits (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "???");
static void
print_pke_unpacktype (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "???");
EXTRACT_FN (dma_next);
PRINT_FN (dma_next);
-const struct txvu_operand txvu_dma_operands[] =
+const struct txvu_operand dma_operands[] =
{
/* place holder (??? not sure if needed) */
#define DMA_UNUSED 128
{ 0 }
};
-struct txvu_opcode txvu_dma_opcodes[] =
+struct txvu_opcode dma_opcodes[] =
{
{ "dmacnt", { DMA_FLAGS, SP, DMA_DATA, C, DMA_NEXT }, 0, 1 },
{ "dmanext", { DMA_FLAGS, SP, DMA_DATA, C, DMA_NEXT }, 0, 2 },
{ "dmareg", { DMA_FLAGS, SP, DMA_DATA, C, DMA_NEXT }, 0, 6 },
{ "dmaend", { DMA_FLAGS, SP, DMA_DATA, C, DMA_NEXT }, 0, 7 }
};
-const int txvu_dma_opcodes_count = sizeof (txvu_dma_opcodes) / sizeof (txvu_dma_opcodes[0]);
+const int dma_opcodes_count = sizeof (dma_opcodes) / sizeof (dma_opcodes[0]);
\f
/* DMA parse,insert,extract,print helper fns. */
char **pstr;
const char **errmsg;
{
+ char *str = *pstr;
+ int flags = 0;
+
+ if (*str != '[')
+ return 0;
+
+ for (str = str + 1; *str != ']'; ++str)
+ {
+ switch (tolower (*str))
+ {
+ case '0' : flags |= DMA_FLAG_PCE0; break;
+ case '1' : flags |= DMA_FLAG_PCE1; break;
+ case 'i' : flags |= DMA_FLAG_INT; break;
+ case 's' : flags |= DMA_FLAG_SPR; break;
+ default : *errmsg = "unknown dma flag"; return 0;
+ }
+ }
+
+ *errmsg = NULL;
+ *pstr = str + 1;
+ return flags;
}
-static TXVU_INSN
+static void
insert_dma_flags (insn, operand, mods, value, errmsg)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
long value;
const char **errmsg;
{
- return 0;
}
static long
extract_dma_flags (insn, operand, mods, pinvalid)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
int *pinvalid;
static void
print_dma_flags (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
- (*info->fprintf_func) (info->stream, "???");
+ if (value)
+ {
+ (*info->fprintf_func) (info->stream, "[");
+ if (value & DMA_FLAG_PCE0)
+ (*info->fprintf_func) (info->stream, "0");
+ if (value & DMA_FLAG_PCE1)
+ (*info->fprintf_func) (info->stream, "1");
+ if (value & DMA_FLAG_INT)
+ (*info->fprintf_func) (info->stream, "i");
+ if (value & DMA_FLAG_SPR)
+ (*info->fprintf_func) (info->stream, "s");
+ (*info->fprintf_func) (info->stream, "]");
+ }
}
static long
{
}
-static TXVU_INSN
+static void
insert_dma_data (insn, operand, mods, value, errmsg)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
long value;
const char **errmsg;
{
- return 0;
}
static long
extract_dma_data (insn, operand, mods, pinvalid)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
int *pinvalid;
static void
print_dma_data (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "???");
{
}
-static TXVU_INSN
+static void
insert_dma_next (insn, operand, mods, value, errmsg)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
long value;
const char **errmsg;
{
- return 0;
}
static long
extract_dma_next (insn, operand, mods, pinvalid)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
int *pinvalid;
static void
print_dma_next (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "???");
EXTRACT_FN (gpuif_eop);
PRINT_FN (gpuif_eop);
-const struct txvu_operand txvu_gpuif_operands[] =
+const struct txvu_operand gpuif_operands[] =
{
/* place holder (??? not sure if needed) */
#define GPUIF_UNUSED 128
{ 0 }
};
-struct txvu_opcode txvu_gpuif_opcodes[] =
+struct txvu_opcode gpuif_opcodes[] =
{
{ "gpuifpacked", { SP, GPUIF_PRIM, C, GPUIF_REGS, C, GPUIF_NLOOP, C, GPUIF_EOP }, 0, 1 },
{ "gpuifreglist", { SP, GPUIF_REGS, C, GPUIF_NLOOP, C, GPUIF_EOP }, 0, 2 },
{ "gpuifimage", { SP, GPUIF_NLOOP }, 0, 3 },
};
-const int txvu_gpuif_opcodes_count = sizeof (txvu_gpuif_opcodes) / sizeof (txvu_gpuif_opcodes[0]);
+const int gpuif_opcodes_count = sizeof (gpuif_opcodes) / sizeof (gpuif_opcodes[0]);
\f
/* GPUIF parse,insert,extract,print helper fns. */
{
}
-static TXVU_INSN
+static void
insert_gpuif_prim (insn, operand, mods, value, errmsg)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
long value;
const char **errmsg;
{
- return 0;
}
static long
extract_gpuif_prim (insn, operand, mods, pinvalid)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
int *pinvalid;
static void
print_gpuif_prim (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "???");
{
}
-static TXVU_INSN
+static void
insert_gpuif_regs (insn, operand, mods, value, errmsg)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
long value;
const char **errmsg;
{
- return 0;
}
static long
extract_gpuif_regs (insn, operand, mods, pinvalid)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
int *pinvalid;
static void
print_gpuif_regs (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "???");
{
}
-static TXVU_INSN
+static void
insert_gpuif_nloop (insn, operand, mods, value, errmsg)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
long value;
const char **errmsg;
{
- return 0;
}
static long
extract_gpuif_nloop (insn, operand, mods, pinvalid)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
int *pinvalid;
static void
print_gpuif_nloop (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "???");
{
}
-static TXVU_INSN
+static void
insert_gpuif_eop (insn, operand, mods, value, errmsg)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
long value;
const char **errmsg;
{
- return 0;
}
static long
extract_gpuif_eop (insn, operand, mods, pinvalid)
- TXVU_INSN insn;
+ TXVU_INSN *insn;
const struct txvu_operand *operand;
int mods;
int *pinvalid;
static void
print_gpuif_eop (info, insn, value)
disassemble_info *info;
- TXVU_INSN insn;
+ TXVU_INSN *insn;
long value;
{
(*info->fprintf_func) (info->stream, "???");
}
+\f
+/* Init fns.
+ These are called before doing each of the respective activities. */
+
+/* Called by the assembler before parsing an instruction. */
+
+void
+txvu_opcode_init_parse ()
+{
+ mnemonic_dest = -1;
+ mnemonic_bc = -1;
+}
+
+/* Called by the disassembler before printing an instruction. */
+
+void
+txvu_opcode_init_print ()
+{
+ mnemonic_dest = -1;
+ mnemonic_bc = -1;
+}
+\f
+/* Indexed by first letter of opcode. Points to chain of opcodes with same
+ first letter. */
+/* ??? One can certainly use a better hash. Later. */
+static struct txvu_opcode *upper_opcode_map[26 + 1];
+static struct txvu_opcode *lower_opcode_map[26 + 1];
+
+/* Indexed by insn code. Points to chain of opcodes with same insn code. */
+static struct txvu_opcode *upper_icode_map[(1 << TXVU_ICODE_HASH_SIZE) - 1];
+static struct txvu_opcode *lower_icode_map[(1 << TXVU_ICODE_HASH_SIZE) - 1];
+\f
+/* Initialize any tables that need it.
+ Must be called once at start up (or when first needed).
+
+ FLAGS is currently unused but is intended to control initialization. */
+
+void
+txvu_opcode_init_tables (flags)
+ int flags;
+{
+ static int init_p = 0;
+
+ /* We may be intentionally called more than once (for example gdb will call
+ us each time the user switches cpu). These tables only need to be init'd
+ once though. */
+ /* ??? We can remove the need for txvu_opcode_supported by taking it into
+ account here, but I'm not sure I want to do that yet (if ever). */
+ if (!init_p)
+ {
+ int i,n;
+
+ /* Upper VU table. */
+
+ memset (upper_opcode_map, 0, sizeof (upper_opcode_map));
+ memset (upper_icode_map, 0, sizeof (upper_icode_map));
+ /* Scan the table backwards so macros appear at the front. */
+ for (i = txvu_upper_opcodes_count - 1; i >= 0; --i)
+ {
+ int opcode_hash = TXVU_HASH_UPPER_OPCODE (txvu_upper_opcodes[i].mnemonic);
+ int icode_hash = TXVU_HASH_UPPER_ICODE (txvu_upper_opcodes[i].value);
+
+ txvu_upper_opcodes[i].next_asm = upper_opcode_map[opcode_hash];
+ upper_opcode_map[opcode_hash] = &txvu_upper_opcodes[i];
+
+ txvu_upper_opcodes[i].next_dis = upper_icode_map[icode_hash];
+ upper_icode_map[icode_hash] = &txvu_upper_opcodes[i];
+ }
+
+ /* Lower VU table. */
+
+ memset (lower_opcode_map, 0, sizeof (lower_opcode_map));
+ memset (lower_icode_map, 0, sizeof (lower_icode_map));
+ /* Scan the table backwards so macros appear at the front. */
+ for (i = txvu_lower_opcodes_count - 1; i >= 0; --i)
+ {
+ int opcode_hash = TXVU_HASH_LOWER_OPCODE (txvu_lower_opcodes[i].mnemonic);
+ int icode_hash = TXVU_HASH_LOWER_ICODE (txvu_lower_opcodes[i].value);
+
+ txvu_lower_opcodes[i].next_asm = lower_opcode_map[opcode_hash];
+ lower_opcode_map[opcode_hash] = &txvu_lower_opcodes[i];
+
+ txvu_lower_opcodes[i].next_dis = lower_icode_map[icode_hash];
+ lower_icode_map[icode_hash] = &txvu_lower_opcodes[i];
+ }
+
+ /* PKE table. */
+
+ for (i = pke_opcodes_count - 2; i >= 0; --i)
+ {
+ pke_opcodes[i].next_asm = & pke_opcodes[i+1];
+ pke_opcodes[i].next_dis = & pke_opcodes[i+1];
+ }
+
+ /* DMA table. */
+
+ for (i = dma_opcodes_count - 2; i >= 0; --i)
+ {
+ dma_opcodes[i].next_asm = & dma_opcodes[i+1];
+ dma_opcodes[i].next_dis = & dma_opcodes[i+1];
+ }
+
+ /* GPUIF table. */
+
+ for (i = gpuif_opcodes_count - 2; i >= 0; --i)
+ {
+ gpuif_opcodes[i].next_asm = & gpuif_opcodes[i+1];
+ gpuif_opcodes[i].next_dis = & gpuif_opcodes[i+1];
+ }
+
+ init_p = 1;
+ }
+}
+
+/* Return the first insn in the chain for assembling upper INSN. */
+
+const struct txvu_opcode *
+txvu_upper_opcode_lookup_asm (insn)
+ const char *insn;
+{
+ return upper_opcode_map[TXVU_HASH_UPPER_OPCODE (insn)];
+}
+
+/* Return the first insn in the chain for disassembling upper INSN. */
+
+const struct txvu_opcode *
+txvu_upper_opcode_lookup_dis (insn)
+ TXVU_INSN insn;
+{
+ return upper_icode_map[TXVU_HASH_UPPER_ICODE (insn)];
+}
+
+/* Return the first insn in the chain for assembling lower INSN. */
+
+const struct txvu_opcode *
+txvu_lower_opcode_lookup_asm (insn)
+ const char *insn;
+{
+ return lower_opcode_map[TXVU_HASH_LOWER_OPCODE (insn)];
+}
+
+/* Return the first insn in the chain for disassembling lower INSN. */
+
+const struct txvu_opcode *
+txvu_lower_opcode_lookup_dis (insn)
+ TXVU_INSN insn;
+{
+ return lower_icode_map[TXVU_HASH_LOWER_ICODE (insn)];
+}
+
+/* Return the first insn in the chain for assembling lower INSN. */
+
+const struct txvu_opcode *
+pke_opcode_lookup_asm (insn)
+ const char *insn;
+{
+ return &pke_opcodes[0];
+}
+
+/* Return the first insn in the chain for disassembling lower INSN. */
+
+const struct txvu_opcode *
+pke_opcode_lookup_dis (insn)
+ TXVU_INSN insn;
+{
+ return &pke_opcodes[0];
+}
+
+/* Return the first insn in the chain for assembling lower INSN. */
+
+const struct txvu_opcode *
+dma_opcode_lookup_asm (insn)
+ const char *insn;
+{
+ return &dma_opcodes[0];
+}
+
+/* Return the first insn in the chain for disassembling lower INSN. */
+
+const struct txvu_opcode *
+dma_opcode_lookup_dis (insn)
+ TXVU_INSN insn;
+{
+ return &dma_opcodes[0];
+}
+
+/* Return the first insn in the chain for assembling lower INSN. */
+
+const struct txvu_opcode *
+gpuif_opcode_lookup_asm (insn)
+ const char *insn;
+{
+ return &gpuif_opcodes[0];
+}
+
+/* Return the first insn in the chain for disassembling lower INSN. */
+
+const struct txvu_opcode *
+gpuif_opcode_lookup_dis (insn)
+ TXVU_INSN insn;
+{
+ return &gpuif_opcodes[0];
+}