* config/tc-dvp.c (md_pseudo_table): Make .quad 16 bytes.

This commit is contained in:
Doug Evans
1998-03-16 18:22:18 +00:00
parent a8ff502679
commit fa3671a34f
2 changed files with 143 additions and 64 deletions

View File

@ -1,3 +1,9 @@
start-sanitize-sky
Mon Mar 16 10:19:44 1998 Doug Evans <devans@canuck.cygnus.com>
* config/tc-dvp.c (md_pseudo_table): Make .quad 16 bytes.
end-sanitize-sky
Fri Mar 13 16:31:38 1998 Tom Tromey <tromey@cygnus.com> Fri Mar 13 16:31:38 1998 Tom Tromey <tromey@cygnus.com>
* depend.c (quote_string_for_make): New function. * depend.c (quote_string_for_make): New function.

View File

@ -51,6 +51,9 @@ static long parse_float PARAMS ((char **, const char **));
static symbolS * create_label PARAMS ((const char *, const char *)); static symbolS * create_label PARAMS ((const char *, const char *));
static symbolS * create_colon_label PARAMS ((int, const char *, const char *)); static symbolS * create_colon_label PARAMS ((int, const char *, const char *));
static char * unique_name PARAMS ((const char *)); static char * unique_name PARAMS ((const char *));
static int compute_nloop PARAMS ((gif_type, int, int));
static void check_nloop PARAMS ((gif_type, int, int, int,
char *, unsigned int));
static long eval_expr PARAMS ((int, int, const char *, ...)); static long eval_expr PARAMS ((int, int, const char *, ...));
static long parse_dma_addr_autocount (); static long parse_dma_addr_autocount ();
static void inline_dma_data PARAMS ((int, DVP_INSN *)); static void inline_dma_data PARAMS ((int, DVP_INSN *));
@ -125,8 +128,10 @@ static const char *dma_data_name;
static gif_type gif_insn_type; static gif_type gif_insn_type;
/* Name of label of current gif<foo> insn's data. */ /* Name of label of current gif<foo> insn's data. */
static const char *gif_data_name; static const char *gif_data_name;
/* Pointer to current gif insn in fragment. */ /* Pointer to frag of current gif insn. */
static char *gif_insn_frag; static fragS *gif_insn_frag;
/* Pointer to current gif insn in gif_insn_frag. */
static char *gif_insn_frag_loc;
/* For variable length instructions, pointer to the initial frag /* For variable length instructions, pointer to the initial frag
and pointer into that frag. These only hold valid values if and pointer into that frag. These only hold valid values if
@ -210,6 +215,7 @@ static void s_state PARAMS ((int));
const pseudo_typeS md_pseudo_table[] = const pseudo_typeS md_pseudo_table[] =
{ {
{ "word", cons, 4 }, { "word", cons, 4 },
{ "quad", cons, 16 },
{ "dmadata", s_dmadata, 0 }, { "dmadata", s_dmadata, 0 },
{ "dmapackvif", s_dmapackvif, 0 }, { "dmapackvif", s_dmapackvif, 0 },
{ "enddirect", s_enddirect, 0 }, { "enddirect", s_enddirect, 0 },
@ -612,7 +618,8 @@ assemble_gif (str)
record_mach (DVP_GIF, 1); record_mach (DVP_GIF, 1);
gif_insn_frag = f = frag_more (16); gif_insn_frag_loc = f = frag_more (16);
gif_insn_frag = frag_now;
for (i = 0; i < 4; ++i) for (i = 0; i < 4; ++i)
md_number_to_chars (f + i * 4, insn_buf[i], 4); md_number_to_chars (f + i * 4, insn_buf[i], 4);
@ -1278,6 +1285,27 @@ md_apply_fix3 (fixP, valueP, seg)
decode_fixup_reloc_type ((int) fixP->fx_r_type, decode_fixup_reloc_type ((int) fixP->fx_r_type,
& cpu, & operand); & cpu, & operand);
/* For the gif nloop operand, if it was specified by the user ensure
it matches the value we computed. */
if (cpu == DVP_GIF
&& (operand - gif_operands) == gif_operand_nloop)
{
value = compute_nloop (fixP->tc_fix_data.type,
fixP->tc_fix_data.nregs,
value);
if (fixP->tc_fix_data.user_nloop != -1)
{
check_nloop (fixP->tc_fix_data.type,
fixP->tc_fix_data.nregs,
fixP->tc_fix_data.user_nloop,
value,
fixP->fx_file, fixP->fx_line);
/* Don't override the user specified value. */
fixP->fx_done = 1;
return 1;
}
}
/* Fetch the instruction, insert the fully resolved operand /* Fetch the instruction, insert the fully resolved operand
value, and stuff the instruction back again. The fixup is recorded value, and stuff the instruction back again. The fixup is recorded
at the appropriate word so pass DVP_MOD_THIS_WORD so any offset at the appropriate word so pass DVP_MOD_THIS_WORD so any offset
@ -1331,7 +1359,7 @@ md_apply_fix3 (fixP, valueP, seg)
md_number_to_chars (where, value, 4); md_number_to_chars (where, value, 4);
break; break;
default: default:
abort (); as_fatal ("unexpected fixup");
} }
} }
@ -1598,6 +1626,52 @@ unique_name (prefix)
++counter; ++counter;
return result; return result;
} }
/* Compute a value for nloop. */
static int
compute_nloop (type, nregs, bytes)
gif_type type;
int nregs, bytes;
{
int computed_nloop;
switch (type)
{
case GIF_PACKED :
/* We can't compute a value if no regs were specified and there is a
non-zero amount of data. Just set to something useful, a warning
will be issued later. */
if (nregs == 0)
nregs = 1;
computed_nloop = (bytes >> 4) / nregs;
break;
case GIF_REGLIST :
if (nregs == 0)
nregs = 1;
computed_nloop = (bytes >> 3) / nregs;
break;
case GIF_IMAGE :
computed_nloop = bytes >> 4;
break;
}
return computed_nloop;
}
/* Issue a warning if the user specified nloop value doesn't match the
computed value. */
static void
check_nloop (type, nregs, user_nloop, computed_nloop, file, line)
gif_type type;
int nregs,user_nloop,computed_nloop;
char *file;
unsigned int line;
{
if (user_nloop != computed_nloop)
as_warn_where (file, line, "nloop value does not match amount of data");
}
/* Compute the auto-count value for a DMA tag. /* Compute the auto-count value for a DMA tag.
INLINE_P is non-zero if the dma data is inline. */ INLINE_P is non-zero if the dma data is inline. */
@ -2183,10 +2257,14 @@ static void
s_endgif (ignore) s_endgif (ignore)
int ignore; int ignore;
{ {
long count; int bytes;
int specified_nloop = gif_nloop (); int specified_nloop = gif_nloop ();
int computed_nloop; int computed_nloop;
int nregs = gif_nregs (); int nregs = gif_nregs ();
char *file;
unsigned int line;
as_where (&file, &line);
if (CUR_ASM_STATE != ASM_GIF) if (CUR_ASM_STATE != ASM_GIF)
{ {
@ -2195,77 +2273,72 @@ s_endgif (ignore)
} }
pop_asm_state (0); pop_asm_state (0);
/* The -16 is because the `gif_data_name' label is emitted at the start /* Fill out to proper boundary.
of the gif tag. */ ??? This may cause eval_expr to always queue a fixup. So be it. */
count = eval_expr (0, 0, ". - %s - 16", gif_data_name);
if (count < 0
|| fixup_count != 0)
{
as_warn ("bad data count");
return;
}
/* Compute a value for nloop.
Also check whether we're left on a double/quadword boundary. */
switch (gif_insn_type) switch (gif_insn_type)
{ {
case GIF_PACKED : case GIF_PACKED : frag_align (4, 0, 0); break;
if (count % 16 != 0) case GIF_REGLIST : frag_align (3, 0, 0); break;
as_warn ("data doesn't fill last quadword"); case GIF_IMAGE : frag_align (4, 0, 0); break;
if (nregs == 0)
{
if (count != 0)
as_warn ("non-zero amount of data, but no registers specified");
computed_nloop = 0;
}
else
computed_nloop = (count >> 4) / nregs;
break;
case GIF_REGLIST :
if (count % 8 != 0)
as_warn ("data doesn't fill last doubleword");
/* Fill out to quadword if odd number of doublewords. */
if (nregs == 0)
{
if (count != 0)
as_warn ("non-zero amount of data, but no registers specified");
computed_nloop = 0;
}
else
computed_nloop = (count >> 3) / nregs;
break;
case GIF_IMAGE :
if (count % 16 != 0)
as_warn ("data doesn't fill last quadword");
computed_nloop = count >> 4;
break;
} }
/* FIXME: How should be handle the case where count is not a proper /* The -16 is because the `gif_data_name' label is emitted at the start
multiple of 8/16? We could just always emit a .align 16 or some of the gif tag. If we're in a different frag from the one we started
such. */ with, this can't be computed until much later. To cope we queue a fixup
and deal with it then.
??? The other way to handle this is by having expr() compute "syma - symb"
when they're in different fragments but the difference is constant.
Not sure how much of a slowdown that will introduce though. */
fixup_count = 0;
bytes = eval_expr (gif_operand_nloop, 0, ". - %s - 16", gif_data_name);
/* Validate nloop if specified. Otherwise write the computed value into /* Compute a value for nloop if we can. */
the insn. */
if (fixup_count == 0)
{
computed_nloop = compute_nloop (gif_insn_type, nregs, bytes);
/* If the user specified nloop, verify it. */
if (specified_nloop != -1) if (specified_nloop != -1)
{ check_nloop (gif_insn_type, nregs, specified_nloop, computed_nloop,
if (computed_nloop != specified_nloop) file, line);
{
as_warn ("nloop value does not match size of data");
return;
} }
/* If computation of nloop can't be done yet, queue a fixup and do it later.
Otherwise validate nloop if specified or write the computed value into
the insn. */
if (fixup_count != 0)
{
/* FIXME: It might eventually be possible to combine all the various
copies of this bit of code. */
int op_type, reloc_type, offset;
const dvp_operand *operand;
fixS *fix;
op_type = fixups[0].opindex;
offset = fixups[0].offset;
reloc_type = encode_fixup_reloc_type (DVP_GIF, op_type);
operand = &gif_operands[op_type];
fix = fix_new_exp (gif_insn_frag,
gif_insn_frag_loc + offset - gif_insn_frag->fr_literal,
4, &fixups[0].exp, 0,
(bfd_reloc_code_real_type) reloc_type);
/* Record user specified value so we can test it when we compute the
actual value. */
fix->tc_fix_data.type = gif_insn_type;
fix->tc_fix_data.nregs = nregs;
fix->tc_fix_data.user_nloop = specified_nloop;
} }
else if (specified_nloop != -1)
; /* nothing to do */
else else
{ {
DVP_INSN insn = bfd_getl32 (gif_insn_frag); DVP_INSN insn = bfd_getl32 (gif_insn_frag_loc);
char *file;
unsigned int line;
as_where (&file, &line);
insert_operand_final (DVP_GIF, &gif_operands[gif_operand_nloop], insert_operand_final (DVP_GIF, &gif_operands[gif_operand_nloop],
DVP_MOD_THIS_WORD, &insn, DVP_MOD_THIS_WORD, &insn,
(offsetT) computed_nloop, file, line); (offsetT) computed_nloop, file, line);
bfd_putl32 ((bfd_vma) insn, gif_insn_frag); bfd_putl32 ((bfd_vma) insn, gif_insn_frag_loc);
} }
gif_data_name = NULL; gif_data_name = NULL;