*** empty log message ***

This commit is contained in:
James Lemke
1998-01-28 02:20:20 +00:00
parent 1f8b7bb9cf
commit 4411d96450
2 changed files with 204 additions and 100 deletions

View File

@ -541,8 +541,20 @@ assemble_one_insn (cpu, opcode, operand_table, str, insn_buf)
if (*str == '\0') if (*str == '\0')
break; break;
/* Is this the special DMA count operand? */
if( operand->flags & TXVU_OPERAND_DMA_COUNT)
txvu_dma_operand_count( 0);
if( (operand->flags & TXVU_OPERAND_DMA_COUNT) && *str == '*')
{
/* Yes, it is!
Remember that we must compute the length later
when the dma-block label (second operand) is known. */
++*pstr;
txvu_dma_operand_count( 1);
}
/* Parse the operand. */ /* Parse the operand. */
if (operand->parse) else if (operand->parse)
{ {
errmsg = NULL; errmsg = NULL;
value = (*operand->parse) (opcode, operand, mods, value = (*operand->parse) (opcode, operand, mods,
@ -1019,7 +1031,7 @@ txvu_insert_operand (insn, cpu, operand, mods, val, file, line)
} }
static void static void
s_dmadata( type) s_dmadata( type)
int type; int type;
{ {
static short state = 0; static short state = 0;
@ -1028,9 +1040,10 @@ s_dmadata( type)
const char *prevName; const char *prevName;
int temp; int temp;
switch( type) { switch( type )
{
case 1: /* .DmaData */ case 1: /* .DmaData */
if( state != 0) if( state != 0 )
{ {
as_bad( "DmaData blocks cannot be nested."); as_bad( "DmaData blocks cannot be nested.");
ignore_rest_of_line(); ignore_rest_of_line();
@ -1045,7 +1058,7 @@ s_dmadata( type)
if( !is_name_beginner( *name) ) if( !is_name_beginner( *name) )
{ {
as_bad( "invalid identifier for \".DmaData\""); as_bad( "invalid identifier for \".DmaData\"");
obstack_1grow (&cond_obstack, 0); obstack_1grow( &cond_obstack, 0);
ignore_rest_of_line(); ignore_rest_of_line();
break; break;
} }
@ -1062,7 +1075,7 @@ s_dmadata( type)
break; break;
case 0: /* .EndDmaData */ case 0: /* .EndDmaData */
if( state != 1) if( state != 1 )
{ {
as_warn( ".EndDmaData encountered outside a DmaData block -- ignored."); as_warn( ".EndDmaData encountered outside a DmaData block -- ignored.");
ignore_rest_of_line(); ignore_rest_of_line();
@ -1100,7 +1113,7 @@ s_dmapackpke( ignore)
char *name; /* points to name of symbol */ char *name; /* points to name of symbol */
SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */
switch( *input_line_pointer++) switch( *input_line_pointer++ )
{ {
case 0: case 0:
dma_pack_pke_p = 0; dma_pack_pke_p = 0;
@ -1146,3 +1159,61 @@ s_vu (enable_p)
{ {
vu_mode_p = enable_p; vu_mode_p = enable_p;
} }
/* Parse a DMA data spec which can be either of '*' or a quad word count. */
static void
parse_dma_count( pstr, errmsg)
char **pstr;
const char **errmsg;
{
char *str = *pstr;
long count;
if( *str == '*' )
{
++*pstr;
/* -1 is a special marker to caller to tell it the count is to be
computed from the data. */
return -1;
}
expressionS exp;
expression( &exp);
if( exp.X_op == O_illegal
|| exp.X_op == O_absent )
break;
else if( exp.X_op == O_constant )
value = exp.X_add_number;
else if( exp.X_op == O_register )
as_fatal( "got O_register");
else
{
/* We need to generate a fixup for this expression. */
if( fixup_count >= MAX_FIXUPS )
as_fatal( "too many fixups");
fixups[fixup_count].exp = exp;
fixups[fixup_count].opindex = index;
++fixup_count;
value = 0;
}
if( isdigit( *str) ) ????????needs to accept an expression
{
char *start = str;
while( *str && *str != ',' )
++str;
if( *str != ',' )
{
*errmsg = "invalid dma count";
return 0;
}
count = atoi (start);
*pstr = str;
return(count);
}
*errmsg = "invalid dma count";
return 0;
}

View File

@ -1797,13 +1797,18 @@ const txvu_operand dma_operands[] =
/* dma data spec */ /* dma data spec */
#define DMA_DATA (DMA_FLAGS + 1) #define DMA_DATA (DMA_FLAGS + 1)
{ 0, 0, 0, { 0, 0, TXVU_OPERAND_DMA_COUNT,
parse_dma_data, insert_dma_data, extract_dma_data, print_dma_data }, 0, insert_dma_data, extract_dma_data, print_dma_data },
/* dma data finalization spec */
#define DMA_DATA2 (DMA_DATA + 1)
{ 0, 0, TXVU_OPERAND_FAKE,
parse_dma_data2, 0, 0, 0},
/* dma next tag spec */ /* dma next tag spec */
#define DMA_NEXT (DMA_DATA + 1) #define DMA_ADDR (DMA_DATA2 + 1)
{ 0, 0, 0, { 0, 0, 0,
parse_dma_next, insert_dma_next, extract_dma_next, print_dma_next }, parse_dma_addr, insert_dma_addr, extract_dma_addr, print_dma_addr},
/* end of list place holder */ /* end of list place holder */
{ 0 } { 0 }
@ -1814,15 +1819,21 @@ struct txvu_opcode dma_opcodes[] =
/* ??? Some of these may take optional arguments. /* ??? Some of these may take optional arguments.
The way to handle that is to have multiple table entries, those with and The way to handle that is to have multiple table entries, those with and
those without the optional arguments. */ those without the optional arguments. */
{ "dmacnt", { DMA_FLAGS, SP, DMA_DATA, C, DMA_NEXT }, 0, 1 }, /*TODO*/ { "dmacall", { DMA_FLAGS, SP, DMA_DATA, C, DMA_ADDR}, 0, 1},
{ "dmanext", { DMA_FLAGS, SP, DMA_DATA, C, DMA_NEXT }, 0, 2 }, /*TODO*/ { "dmacnt", { DMA_FLAGS, SP, DMA_DATA, C, DMA_ADDR}, 0, 2},
{ "dmaref", { DMA_FLAGS, SP, DMA_DATA, C, DMA_NEXT }, 0, 3 }, { "dmaend", { DMA_FLAGS, SP, DMA_DATA, DMA_DATA2}, 0, 3},
{ "dmarefs", { DMA_FLAGS, SP, DMA_DATA, C, DMA_NEXT }, 0, 4 }, { "dmaend", { DMA_FLAGS, SP, DMA_DATA, C, DMA_ADDR}, 0, 4},
{ "dmacall", { DMA_FLAGS, SP, DMA_DATA, C, DMA_NEXT }, 0, 5 }, /*TODO*/ { "dmanext", { DMA_FLAGS, SP, DMA_DATA, C, DMA_ADDR}, 0, 5},
{ "dmaret", { DMA_FLAGS, SP, DMA_DATA, C, DMA_NEXT }, 0, 6 }, /*TODO { "dmaref", { DMA_FLAGS, SP, DMA_DATA, C, DMA_PTR_ADDR}, 0, 6}, */
{ "dmaend", { DMA_FLAGS, SP, DMA_DATA, C, DMA_NEXT }, 0, 7 } /*TODO { "dmarefs", { DMA_FLAGS, SP, DMA_DATA, C, DMA_PTR_ADDR}, 0, 7}, */
/*TODO*/ { "dmaret", { DMA_FLAGS, SP, DMA_DATA, DMA_DATA2}, 0, 8}
/*TODO*/ { "dmaret", { DMA_FLAGS, SP, DMA_DATA, C, DMA_ADDR}, 0, 9}
}; };
const int dma_opcodes_count = sizeof (dma_opcodes) / sizeof (dma_opcodes[0]); const int dma_opcodes_count = sizeof (dma_opcodes) / sizeof (dma_opcodes[0]);
/* Did the current DMA instruction has specify "*" as its length operand?
-1=uninitialized, 0=no, 1=yes. */
static int state_dma_operand_count_p;
/* DMA parse,insert,extract,print helper fns. */ /* DMA parse,insert,extract,print helper fns. */
@ -1902,44 +1913,23 @@ print_dma_flags (opcode, operand, mods, insn, info, value)
} }
} }
/* Parse a DMA data spec which can be either of '*' or a quad word count. */
static long static long
parse_dma_data (opcode, operand, mods, pstr, errmsg) parse_dma_data2( opcode, operand, mods, pstr, errmsg)
const txvu_opcode *opcode; const txvu_opcode *opcode;
const txvu_operand *operand; const txvu_operand *operand;
int mods; int mods;
char **pstr; char **pstr;
const char **errmsg; const char **errmsg;
{ {
char *str = *pstr; /*
long count; If txvu_dma_operand_count() < 0 error
if txvu_dma_operand_count() > 0
if (*str == '*') if dmaref || dmarefs
{ compute from two related symbols
++*pstr; else
/* -1 is a special marker to caller to tell it the count is to be compute from current addr and end symbol
computed from the data. */ store value to count field?
return -1; */
}
if (isdigit (*str))
{
char *start = str;
while (*str && *str != ',')
++str;
if (*str != ',')
{
*errmsg = "invalid dma count";
return 0;
}
count = atoi (start);
*pstr = str;
return count;
}
*errmsg = "invalid dma count";
return 0;
} }
static void static void
@ -1977,7 +1967,7 @@ print_dma_data (opcode, operand, mods, insn, info, value)
} }
static long static long
parse_dma_next (opcode, operand, mods, pstr, errmsg) parse_dma_addr (opcode, operand, mods, pstr, errmsg)
const txvu_opcode *opcode; const txvu_opcode *opcode;
const txvu_operand *operand; const txvu_operand *operand;
int mods; int mods;
@ -1985,20 +1975,42 @@ parse_dma_next (opcode, operand, mods, pstr, errmsg)
const char **errmsg; const char **errmsg;
{ {
char *start = *pstr; char *start = *pstr;
char *end = scan_symbol (start); char *end = scan_symbol( start);
if (end == start) if( end == start )
{ {
*errmsg = "invalid dma next tag"; *errmsg = "invalid dma next tag";
return 0; return 0;
} }
/* FIXME: unfinished */
/* FIXME: unfinished
if txvu_dma_operand_count() > 0
if dmaref || dmarefs
this operand must be a symbol (vs an expression)
lookup the symbol
store the symbol's value in the addr field (relocs?)
compute the end_symbol's name
lookup the end_symbol
if not found: error
compute the length as _$<name>-<name>
else
evaluate the operand as an expression
store the value to the count field
compute the length as _$EndDma-.
store the count field
else
evaluate the operand as an expression
store the value to the count field
*/
parse_dma_data2( opcode, operand, mods, pstr, errmsg);
*pstr = end; *pstr = end;
return 0; return 0;
} }
static void static void
insert_dma_next (opcode, operand, mods, insn, value, errmsg) insert_dma_addr (opcode, operand, mods, insn, value, errmsg)
const txvu_opcode *opcode; const txvu_opcode *opcode;
const txvu_operand *operand; const txvu_operand *operand;
int mods; int mods;
@ -2009,7 +2021,7 @@ insert_dma_next (opcode, operand, mods, insn, value, errmsg)
} }
static long static long
extract_dma_next (opcode, operand, mods, insn, pinvalid) extract_dma_addr (opcode, operand, mods, insn, pinvalid)
const txvu_opcode *opcode; const txvu_opcode *opcode;
const txvu_operand *operand; const txvu_operand *operand;
int mods; int mods;
@ -2020,7 +2032,7 @@ extract_dma_next (opcode, operand, mods, insn, pinvalid)
} }
static void static void
print_dma_next (opcode, operand, mods, insn, info, value) print_dma_addr (opcode, operand, mods, insn, info, value)
const txvu_opcode *opcode; const txvu_opcode *opcode;
const txvu_operand *operand; const txvu_operand *operand;
int mods; int mods;
@ -2435,6 +2447,27 @@ txvu_opcode_init_parse ()
state_vu_mnemonic_bc = -1; state_vu_mnemonic_bc = -1;
state_pke_varlen_p = -1; state_pke_varlen_p = -1;
state_pke_len = -1; state_pke_len = -1;
state_dma_operand_count_p = -1;
}
/*
Query or set the current type of a DMA length operand, explicit or computed by "as".
The return value is the setting before "action" is applied:
-1=uninitialized, 0=explicit, +1=computed
The value of "action" is interpreted as:
-1=no change, 0=set explicit, +1=set computed
*/
int
txvu_dma_operand_count( action)
{
int result = state_dma_operand_count;
if( action == 0)
state_dma_operand_count = 0;
else if( action > 0)
state_dma_operand_count_p = 1;
return result;
} }
/* Called by the disassembler before printing an instruction. */ /* Called by the disassembler before printing an instruction. */