Implement DMAcnt, DMAret & DMAend with explicit count args.

This commit is contained in:
James Lemke
1998-01-31 00:04:26 +00:00
parent 83f3596372
commit 3b2215c2ed

View File

@ -125,6 +125,8 @@ static subsegT prev_subseg;
static segT prev_seg; static segT prev_seg;
static void s_dmadata PARAMS ((int)); static void s_dmadata PARAMS ((int));
static void s_dmadata_implied PARAMS ((int));
static void s_enddmadata PARAMS ((int));
static void s_dmapackpke PARAMS ((int)); static void s_dmapackpke PARAMS ((int));
static void s_enddirect PARAMS ((int)); static void s_enddirect PARAMS ((int));
static void s_endgpuif PARAMS ((int)); static void s_endgpuif PARAMS ((int));
@ -135,10 +137,10 @@ static void s_state PARAMS ((int));
/* The target specific pseudo-ops which we support. */ /* The target specific pseudo-ops which we support. */
const pseudo_typeS md_pseudo_table[] = const pseudo_typeS md_pseudo_table[] =
{ {
{ "dmadata", s_dmadata, 1 }, { "dmadata", s_dmadata, 0 },
{ "dmapackpke", s_dmapackpke, 0 }, { "dmapackpke", s_dmapackpke, 0 },
{ "enddirect", s_enddirect, 0 }, { "enddirect", s_enddirect, 0 },
{ "enddmadata", s_dmadata, 0 }, { "enddmadata", s_enddmadata, 0 },
{ "endgpuif", s_endgpuif, 0 }, { "endgpuif", s_endgpuif, 0 },
{ "endmpg", s_endmpg, 0 }, { "endmpg", s_endmpg, 0 },
{ "endunpack", s_endunpack, 0 }, { "endunpack", s_endunpack, 0 },
@ -241,15 +243,62 @@ assemble_dma (str)
char *str; char *str;
{ {
DVP_INSN insn_buf[4]; DVP_INSN insn_buf[4];
int len; /* Insn's length, in 32 bit words. */
char *f; /* Pointer to allocated frag. */
int i;
const dvp_opcode *opcode; const dvp_opcode *opcode;
/*
Fill the first two words with PKE NOPs.
They may be over-written later if DmaPackPke is on.
initialize the remainder with zeros.
*/
insn_buf[ 0] = 0;
insn_buf[ 1] = 0;
insn_buf[ 2] = 0;
insn_buf[ 3] = 0;
opcode = assemble_one_insn (DVP_DMA, opcode = assemble_one_insn (DVP_DMA,
dma_opcode_lookup_asm (str), dma_operands, dma_opcode_lookup_asm (str), dma_operands,
&str, insn_buf); &str, insn_buf);
if (opcode == NULL) if( opcode == NULL) return;
return; if( !output_dma) return;
if (! output_dma)
return; len = 4;
f = frag_more( len * 4);
/* Write out the PKE / DMA instructions. */
for( i = 0; i < len; ++i)
md_number_to_chars( f + i * 4, insn_buf[i], 4);
/* Create any fixups. */
/* FIXME: It might eventually be possible to combine all the various
copies of this bit of code. */
for( i = 0; i < fixup_count; ++i)
{
int op_type, reloc_type, offset;
const dvp_operand *operand;
#if 0
/*
Create a fixup for this operand.
At this point we do not use a bfd_reloc_code_real_type for
operands residing in the insn, but instead just use the
operand index. This lets us easily handle fixups for any
operand type, although that is admittedly not a very exciting
feature. We pick a BFD reloc type in md_apply_fix.
*/
op_type = fixups[i].opindex;
offset = fixups[i].offset;
reloc_type = encode_fixup_reloc_type (DVP_PKE, op_type);
operand = &pke_operands[op_type];
fix_new_exp (frag_now, f + offset - frag_now->fr_literal, 4,
&fixups[i].exp,
(operand->flags & DVP_OPERAND_RELATIVE_BRANCH) != 0,
(bfd_reloc_code_real_type) reloc_type);
#endif
}
} }
/* Subroutine of md_assemble to assemble PKE instructions. */ /* Subroutine of md_assemble to assemble PKE instructions. */
@ -510,7 +559,7 @@ assemble_one_insn (cpu, opcode, operand_table, pstr, insn_buf)
/* Scan the syntax string. If it doesn't match, try the next one. */ /* Scan the syntax string. If it doesn't match, try the next one. */
dvp_opcode_init_parse (); dvp_opcode_init_parse ();
*insn_buf = opcode->value; insn_buf[ opcode->opcode_word] = opcode->value;
fixup_count = 0; fixup_count = 0;
past_opcode_p = 0; past_opcode_p = 0;
num_suffixes = 0; num_suffixes = 0;
@ -641,6 +690,13 @@ assemble_one_insn (cpu, opcode, operand_table, pstr, insn_buf)
} }
#endif #endif
if( operand->flags & DVP_OPERAND_DMA_ILD)
{
s_dmadata_implied( 0);
++syn;
break;
}
/* Is there anything left to parse? /* Is there anything left to parse?
We don't check for this at the top because we want to parse We don't check for this at the top because we want to parse
any trailing fake arguments in the syntax string. */ any trailing fake arguments in the syntax string. */
@ -648,35 +704,19 @@ assemble_one_insn (cpu, opcode, operand_table, pstr, insn_buf)
if (*str == '\0') if (*str == '\0')
break; break;
#if 0 /* Parse the operand. */
/* Is this the special DMA count operand? */
if( operand->flags & DVP_OPERAND_DMA_COUNT)
dvp_dma_operand_autocount( 0);
if( (operand->flags & DVP_OPERAND_DMA_COUNT) && *str == '*')
{
/* Yes, it is!
Remember that we must compute the length later
when the dma-block label (second operand) is known. */
++str;
dvp_dma_operand_autocount( 1);
}
#endif
if( operand->flags & DVP_OPERAND_DMA_ILD_AUTOCOUNT) if( operand->flags & DVP_OPERAND_DMA_ILD_AUTOCOUNT)
{ {
errmsg = 0; errmsg = 0;
value = parse_dma_ild_autocount( opcode, operand, mods, insn_buf, &str, &errmsg); value = parse_dma_ild_autocount( opcode, operand, mods, insn_buf, &str, &errmsg);
if( errmsg) break; if( errmsg) break;
} }
else if( operand->flags & DVP_OPERAND_DMA_PTR_AUTOCOUNT)
if( operand->flags & DVP_OPERAND_DMA_PTR_AUTOCOUNT)
{ {
errmsg = 0; errmsg = 0;
value = parse_dma_ptr_autocount( opcode, operand, mods, insn_buf, &str, &errmsg); value = parse_dma_ptr_autocount( opcode, operand, mods, insn_buf, &str, &errmsg);
if( errmsg) break; if( errmsg) break;
} }
/* Parse the operand. */
else if (operand->parse) else if (operand->parse)
{ {
errmsg = NULL; errmsg = NULL;
@ -1323,16 +1363,12 @@ insert_operand (cpu, opcode, operand, mods, insn_buf, val, errmsg)
else else
{ {
/* We currently assume a field does not cross a word boundary. */ /* We currently assume a field does not cross a word boundary. */
int shift = ((mods & DVP_MOD_THIS_WORD)
? (operand->shift & 31)
: operand->shift);
DVP_INSN *p = insn_buf + (shift / 32);
if (operand->bits == 32) if (operand->bits == 32)
*p = val; insn_buf[ operand->word] = val;
else else
{ {
shift = shift % 32; long temp = (long) val & ((1 << operand->bits) - 1);
*p |= ((long) val & ((1 << operand->bits) - 1)) << shift; insn_buf[ operand->word] |= temp << operand->shift;
} }
} }
} }
@ -1408,27 +1444,39 @@ insert_operand_final (cpu, operand, mods, insn_buf, val, file, line)
} }
} }
static void static short dmadata_state = 0;
s_dmadata( type) static const char *dmadata_name;
int type;
{
static short state = 0;
static symbolS *label; /* Points to symbol */
char *name;
const char *prevName;
int temp;
switch( type ) /* Non-zero if .DmaData was implied by a real (non-pseudo) opcode. */
static int implied_dmadata_p = 0;
static void
s_dmadata_implied( ignore)
int ignore;
{
if( dmadata_state != 0 )
{ {
case 1: /* .DmaData */ as_bad( "DmaData blocks cannot be nested.");
if( state != 0 ) }
dmadata_state = 1;
dmadata_name = 0;
}
static void
s_dmadata( ignore)
int ignore;
{
char *name, c;
dmadata_name = 0;
if( dmadata_state != 0 )
{ {
as_bad( "DmaData blocks cannot be nested."); as_bad( "DmaData blocks cannot be nested.");
ignore_rest_of_line(); ignore_rest_of_line();
state = 1; return;
break;
} }
state = 1; dmadata_state = 1;
SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */
name = input_line_pointer; name = input_line_pointer;
@ -1436,52 +1484,50 @@ 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); /*FIXME what is this for?*/
ignore_rest_of_line(); ignore_rest_of_line();
break; return;
} }
else
{
char c;
c = get_symbol_end(); c = get_symbol_end();
line_label = label = colon( name); /* user-defined label */ line_label = colon( name); /* user-defined label */
dmadata_name = line_label->bsym->name;
*input_line_pointer = c; *input_line_pointer = c;
demand_empty_rest_of_line(); demand_empty_rest_of_line();
} /* if a valid identifyer name */ }
break;
case 0: /* .EndDmaData */ static void
if( state != 1 ) s_enddmadata( ignore)
int ignore;
{
if( dmadata_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();
state = 0; dmadata_name = 0;
break;
} }
state = 0; dmadata_state = 0;
demand_empty_rest_of_line(); demand_empty_rest_of_line();
/* /*
* "label" points to beginning of block * "label" points to beginning of block
* Create a name for the final label like _$<name> * Create a name for the final label like _$<name>
*/ */
prevName = label->bsym->name; if( dmadata_name) {
temp = strlen( prevName) + 1; int temp;
char *name;
temp = strlen( dmadata_name) + 1;
name = xmalloc( temp + 2); name = xmalloc( temp + 2);
name[ 0] = '_'; name[ 0] = '_';
name[ 1] = '$'; name[ 1] = '$';
memcpy( name+2, prevName, temp); /* copy original name & \0 */ memcpy( name+2, dmadata_name, temp); /* copy original name & \0 */
colon( name); colon( name);
free( name); free( name);
break;
default:
as_assert( __FILE__, __LINE__, 0);
} }
} }
static void static void
s_dmapackpke( ignore) s_dmapackpke( ignore)
int ignore; int ignore;
@ -1493,10 +1539,10 @@ s_dmapackpke( ignore)
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;
break; break;
case 1: case '1':
dma_pack_pke_p = 1; dma_pack_pke_p = 1;
break; break;
default: default: