mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 20:28:28 +08:00
(asm_state): New state ASM_GIF.
(gif_{insn_type,data_name,insn_frag}): New static locals. (md_assemble): Watch for .endgif if in ASM_GIF state. (assemble_gif): Complete. (s_endgif): Complete.
This commit is contained in:
@ -5,6 +5,11 @@ Fri Feb 20 12:43:02 1998 Doug Evans <devans@canuck.cygnus.com>
|
|||||||
(dvp_parse_done): Comment out contents.
|
(dvp_parse_done): Comment out contents.
|
||||||
(s_enddirect,s_endmpg,s_endunpack): Call demand_empty_rest_of_line.
|
(s_enddirect,s_endmpg,s_endunpack): Call demand_empty_rest_of_line.
|
||||||
(s_state): Handle .vu in included file.
|
(s_state): Handle .vu in included file.
|
||||||
|
(asm_state): New state ASM_GIF.
|
||||||
|
(gif_{insn_type,data_name,insn_frag}): New static locals.
|
||||||
|
(md_assemble): Watch for .endgif if in ASM_GIF state.
|
||||||
|
(assemble_gif): Complete.
|
||||||
|
(s_endgif): Complete.
|
||||||
|
|
||||||
end-sanitize-sky
|
end-sanitize-sky
|
||||||
Fri Feb 20 15:03:13 1998 Ian Lance Taylor <ian@cygnus.com>
|
Fri Feb 20 15:03:13 1998 Ian Lance Taylor <ian@cygnus.com>
|
||||||
|
@ -49,7 +49,7 @@ static struct symbol * create_colon_label PARAMS ((const char *, const char *));
|
|||||||
static char * unique_name PARAMS ((void));
|
static char * unique_name PARAMS ((void));
|
||||||
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_dmadata PARAMS ((int, DVP_INSN *));
|
static void inline_dma_data PARAMS ((int, DVP_INSN *));
|
||||||
static void setup_autocount PARAMS ((const char *, DVP_INSN *));
|
static void setup_autocount PARAMS ((const char *, DVP_INSN *));
|
||||||
|
|
||||||
static void insert_operand
|
static void insert_operand
|
||||||
@ -76,14 +76,21 @@ const char FLT_CHARS[] = "dD";
|
|||||||
be provided. (e.g. mpg is followed by vu insns until a .EndMpg is
|
be provided. (e.g. mpg is followed by vu insns until a .EndMpg is
|
||||||
seen). */
|
seen). */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ASM_INIT, ASM_MPG, ASM_DIRECT, ASM_UNPACK, ASM_VU
|
ASM_INIT, ASM_MPG, ASM_DIRECT, ASM_UNPACK, ASM_VU, ASM_GIF
|
||||||
} asm_state;
|
} asm_state;
|
||||||
static asm_state cur_asm_state = ASM_INIT;
|
static asm_state cur_asm_state = ASM_INIT;
|
||||||
|
|
||||||
/* Nonzero if inside .DmaData. */
|
/* Nonzero if inside .DmaData. */
|
||||||
static int dmadata_state = 0;
|
static int dma_data_state = 0;
|
||||||
/* Label of .DmaData (internally generated for inline data). */
|
/* Label of .DmaData (internally generated for inline data). */
|
||||||
static const char *dmadata_name;
|
static const char *dma_data_name;
|
||||||
|
|
||||||
|
/* Type of gif tag. */
|
||||||
|
static gif_type gif_insn_type;
|
||||||
|
/* Name of label of current gif<foo> insn's data. */
|
||||||
|
static const char *gif_data_name;
|
||||||
|
/* Pointer to current gif insn in fragment. */
|
||||||
|
static char *gif_insn_frag;
|
||||||
|
|
||||||
/* 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
|
||||||
@ -154,6 +161,7 @@ static void s_dmadata PARAMS ((int));
|
|||||||
static void s_enddmadata PARAMS ((int));
|
static void s_enddmadata PARAMS ((int));
|
||||||
static void s_dmapackvif PARAMS ((int));
|
static void s_dmapackvif PARAMS ((int));
|
||||||
static void s_enddirect PARAMS ((int));
|
static void s_enddirect PARAMS ((int));
|
||||||
|
static void s_endgif PARAMS ((int));
|
||||||
static void s_endmpg PARAMS ((int));
|
static void s_endmpg PARAMS ((int));
|
||||||
static void s_endunpack PARAMS ((int));
|
static void s_endunpack PARAMS ((int));
|
||||||
static void s_state PARAMS ((int));
|
static void s_state PARAMS ((int));
|
||||||
@ -166,6 +174,7 @@ const pseudo_typeS md_pseudo_table[] =
|
|||||||
{ "dmapackvif", s_dmapackvif, 0 },
|
{ "dmapackvif", s_dmapackvif, 0 },
|
||||||
{ "enddirect", s_enddirect, 0 },
|
{ "enddirect", s_enddirect, 0 },
|
||||||
{ "enddmadata", s_enddmadata, 0 },
|
{ "enddmadata", s_enddmadata, 0 },
|
||||||
|
{ "endgif", s_endgif, 0 },
|
||||||
{ "endmpg", s_endmpg, 0 },
|
{ "endmpg", s_endmpg, 0 },
|
||||||
{ "endunpack", s_endunpack, 0 },
|
{ "endunpack", s_endunpack, 0 },
|
||||||
/* .vu added to simplify debugging and creation of input files */
|
/* .vu added to simplify debugging and creation of input files */
|
||||||
@ -243,6 +252,13 @@ md_assemble (str)
|
|||||||
while (isspace (*str))
|
while (isspace (*str))
|
||||||
str++;
|
str++;
|
||||||
|
|
||||||
|
/* After a gif tag, no insns can appear until a .endgif is seen. */
|
||||||
|
if (cur_asm_state == ASM_GIF)
|
||||||
|
{
|
||||||
|
as_bad ("missing .endgif");
|
||||||
|
cur_asm_state = ASM_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
if (cur_asm_state == ASM_INIT)
|
if (cur_asm_state == ASM_INIT)
|
||||||
{
|
{
|
||||||
if (strncasecmp (str, "dma", 3) == 0)
|
if (strncasecmp (str, "dma", 3) == 0)
|
||||||
@ -446,12 +462,40 @@ assemble_gif (str)
|
|||||||
{
|
{
|
||||||
DVP_INSN insn_buf[4];
|
DVP_INSN insn_buf[4];
|
||||||
const dvp_opcode *opcode;
|
const dvp_opcode *opcode;
|
||||||
|
char *f;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
insn_buf[0] = insn_buf[1] = insn_buf[2] = insn_buf[3] = 0;
|
||||||
|
|
||||||
opcode = assemble_one_insn (DVP_GIF,
|
opcode = assemble_one_insn (DVP_GIF,
|
||||||
gif_opcode_lookup_asm (str), gif_operands,
|
gif_opcode_lookup_asm (str), gif_operands,
|
||||||
&str, insn_buf);
|
&str, insn_buf);
|
||||||
if (opcode == NULL)
|
if (opcode == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Do an implicit alignment to a 16 byte boundary. */
|
||||||
|
frag_align (4, 0, 0);
|
||||||
|
record_alignment (now_seg, 4);
|
||||||
|
|
||||||
|
gif_insn_frag = f = frag_more (16);
|
||||||
|
for (i = 0; i < 4; ++i)
|
||||||
|
md_number_to_chars (f + i * 4, insn_buf[i], 4);
|
||||||
|
|
||||||
|
/* Insert a label so we can compute the number of quadwords when the
|
||||||
|
.endgif is seen. */
|
||||||
|
gif_data_name = S_GET_NAME (create_colon_label ("", unique_name ()));
|
||||||
|
|
||||||
|
/* Record the type of the gif tag so we know how to compute nloop
|
||||||
|
in s_endgif. */
|
||||||
|
if (strcmp (opcode->mnemonic, "gifpacked") == 0)
|
||||||
|
gif_insn_type = GIF_PACKED;
|
||||||
|
else if (strcmp (opcode->mnemonic, "gifreglist") == 0)
|
||||||
|
gif_insn_type = GIF_REGLIST;
|
||||||
|
else if (strcmp (opcode->mnemonic, "gifimage") == 0)
|
||||||
|
gif_insn_type = GIF_IMAGE;
|
||||||
|
else
|
||||||
|
abort ();
|
||||||
|
cur_asm_state = ASM_GIF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Subroutine of md_assemble to assemble VU instructions. */
|
/* Subroutine of md_assemble to assemble VU instructions. */
|
||||||
@ -636,7 +680,7 @@ assemble_one_insn (cpu, opcode, operand_table, pstr, insn_buf)
|
|||||||
|
|
||||||
if (operand->flags & DVP_OPERAND_DMA_INLINE)
|
if (operand->flags & DVP_OPERAND_DMA_INLINE)
|
||||||
{
|
{
|
||||||
inline_dmadata ((mods & DVP_OPERAND_AUTOCOUNT) != 0,
|
inline_dma_data ((mods & DVP_OPERAND_AUTOCOUNT) != 0,
|
||||||
insn_buf);
|
insn_buf);
|
||||||
++syn;
|
++syn;
|
||||||
continue;
|
continue;
|
||||||
@ -1196,7 +1240,9 @@ scan_symbol (sym)
|
|||||||
/* Evaluate an expression.
|
/* Evaluate an expression.
|
||||||
The result is the value of the expression if it can be evaluated,
|
The result is the value of the expression if it can be evaluated,
|
||||||
or 0 if it cannot (say because some symbols haven't been defined yet)
|
or 0 if it cannot (say because some symbols haven't been defined yet)
|
||||||
in which case a fixup is queued. */
|
in which case a fixup is queued.
|
||||||
|
|
||||||
|
If OPINDEX is 0, don't queue any fixups, just return 0. */
|
||||||
|
|
||||||
static long
|
static long
|
||||||
#ifdef USE_STDARG
|
#ifdef USE_STDARG
|
||||||
@ -1229,11 +1275,14 @@ eval_expr (opindex, offset, fmt, va_alist)
|
|||||||
if (exp.X_op == O_constant)
|
if (exp.X_op == O_constant)
|
||||||
value = exp.X_add_number;
|
value = exp.X_add_number;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (opindex != 0)
|
||||||
{
|
{
|
||||||
fixups[fixup_count].exp = exp;
|
fixups[fixup_count].exp = exp;
|
||||||
fixups[fixup_count].opindex = opindex;
|
fixups[fixup_count].opindex = opindex;
|
||||||
fixups[fixup_count].offset = offset;
|
fixups[fixup_count].offset = offset;
|
||||||
++fixup_count;
|
++fixup_count;
|
||||||
|
}
|
||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
@ -1315,25 +1364,25 @@ setup_autocount (name, insn_buf)
|
|||||||
/* Record that inline data follows. */
|
/* Record that inline data follows. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
inline_dmadata (autocount_p, insn_buf)
|
inline_dma_data (autocount_p, insn_buf)
|
||||||
int autocount_p;
|
int autocount_p;
|
||||||
DVP_INSN *insn_buf;
|
DVP_INSN *insn_buf;
|
||||||
{
|
{
|
||||||
if (dmadata_state != 0 )
|
if (dma_data_state != 0 )
|
||||||
{
|
{
|
||||||
as_bad ("DmaData blocks cannot be nested.");
|
as_bad ("DmaData blocks cannot be nested.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dmadata_state = 1;
|
dma_data_state = 1;
|
||||||
|
|
||||||
if (autocount_p)
|
if (autocount_p)
|
||||||
{
|
{
|
||||||
dmadata_name = S_GET_NAME (create_colon_label ("", unique_name ()));
|
dma_data_name = S_GET_NAME (create_colon_label ("", unique_name ()));
|
||||||
setup_autocount (dmadata_name, insn_buf);
|
setup_autocount (dma_data_name, insn_buf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dmadata_name = 0;
|
dma_data_name = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute the auto-count value for a DMA tag with out-of-line data. */
|
/* Compute the auto-count value for a DMA tag with out-of-line data. */
|
||||||
@ -1514,17 +1563,21 @@ insert_operand (cpu, opcode, operand, mods, insn_buf, val, errmsg)
|
|||||||
int shift = ((mods & DVP_MOD_THIS_WORD)
|
int shift = ((mods & DVP_MOD_THIS_WORD)
|
||||||
? (operand->shift & 31)
|
? (operand->shift & 31)
|
||||||
: operand->shift);
|
: operand->shift);
|
||||||
int word = (mods & DVP_MOD_THIS_WORD) ? 0 : operand->word;
|
/* FIXME: revisit */
|
||||||
#if 0 /* FIXME: revisit */
|
if (operand->word == 0)
|
||||||
DVP_INSN *p = insn_buf + (shift / 32);
|
{
|
||||||
|
int word = (mods & DVP_MOD_THIS_WORD) ? 0 : (shift / 32);
|
||||||
if (operand->bits == 32)
|
if (operand->bits == 32)
|
||||||
*p = val;
|
insn_buf[word] = val;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shift = shift % 32;
|
shift = shift % 32;
|
||||||
*p |= ((long) val & ((1 << operand->bits) - 1)) << shift;
|
insn_buf[word] |= ((long) val & ((1 << operand->bits) - 1)) << shift;
|
||||||
}
|
}
|
||||||
#else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int word = (mods & DVP_MOD_THIS_WORD) ? 0 : operand->word;
|
||||||
if (operand->bits == 32)
|
if (operand->bits == 32)
|
||||||
insn_buf[word] = val;
|
insn_buf[word] = val;
|
||||||
else
|
else
|
||||||
@ -1533,7 +1586,7 @@ insert_operand (cpu, opcode, operand, mods, insn_buf, val, errmsg)
|
|||||||
insn_buf[word] |= temp << operand->shift;
|
insn_buf[word] |= temp << operand->shift;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insert an operand's final value into an instruction.
|
/* Insert an operand's final value into an instruction.
|
||||||
@ -1614,15 +1667,15 @@ s_dmadata (ignore)
|
|||||||
{
|
{
|
||||||
char *name, c;
|
char *name, c;
|
||||||
|
|
||||||
dmadata_name = 0;
|
dma_data_name = 0;
|
||||||
|
|
||||||
if (dmadata_state != 0)
|
if (dma_data_state != 0)
|
||||||
{
|
{
|
||||||
as_bad ("DmaData blocks cannot be nested.");
|
as_bad ("DmaData blocks cannot be nested.");
|
||||||
ignore_rest_of_line ();
|
ignore_rest_of_line ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dmadata_state = 1;
|
dma_data_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;
|
||||||
@ -1636,7 +1689,7 @@ s_dmadata (ignore)
|
|||||||
|
|
||||||
c = get_symbol_end ();
|
c = get_symbol_end ();
|
||||||
line_label = colon (name); /* user-defined label */
|
line_label = colon (name); /* user-defined label */
|
||||||
dmadata_name = S_GET_NAME (line_label);
|
dma_data_name = S_GET_NAME (line_label);
|
||||||
*input_line_pointer = c;
|
*input_line_pointer = c;
|
||||||
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
@ -1646,23 +1699,23 @@ static void
|
|||||||
s_enddmadata (ignore)
|
s_enddmadata (ignore)
|
||||||
int ignore;
|
int ignore;
|
||||||
{
|
{
|
||||||
if (dmadata_state != 1)
|
if (dma_data_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 ();
|
||||||
dmadata_name = 0;
|
dma_data_name = 0;
|
||||||
}
|
}
|
||||||
dmadata_state = 0;
|
dma_data_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>. */
|
||||||
if (dmadata_name)
|
if (dma_data_name)
|
||||||
{
|
{
|
||||||
/* Fill the data out to a multiple of 16 bytes. */
|
/* Fill the data out to a multiple of 16 bytes. */
|
||||||
/* FIXME: Does the fill contents matter? */
|
/* FIXME: Does the fill contents matter? */
|
||||||
frag_align (4, 0, 0);
|
frag_align (4, 0, 0);
|
||||||
create_colon_label (END_LABEL_PREFIX, dmadata_name);
|
create_colon_label (END_LABEL_PREFIX, dma_data_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1719,6 +1772,70 @@ s_enddirect (ignore)
|
|||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s_endgif (ignore)
|
||||||
|
int ignore;
|
||||||
|
{
|
||||||
|
long count;
|
||||||
|
int nloop = gif_nloop ();
|
||||||
|
|
||||||
|
if (cur_asm_state != ASM_GIF)
|
||||||
|
{
|
||||||
|
as_bad (".endgif doesn't follow a gif tag");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cur_asm_state = ASM_INIT;
|
||||||
|
|
||||||
|
if (gif_insn_type == GIF_PACKED)
|
||||||
|
count = eval_expr (0, 0, "(. - %s) >> 4", gif_data_name);
|
||||||
|
else
|
||||||
|
count = eval_expr (0, 0, "(. - %s) >> 3", gif_data_name);
|
||||||
|
|
||||||
|
if (count < 0
|
||||||
|
|| fixup_count != 0)
|
||||||
|
{
|
||||||
|
as_bad ("bad data count");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate nloop if specified. Otherwise write the computed value into
|
||||||
|
the insn. */
|
||||||
|
if (nloop != -1)
|
||||||
|
{
|
||||||
|
int ok_p;
|
||||||
|
|
||||||
|
switch (gif_insn_type)
|
||||||
|
{
|
||||||
|
case GIF_PACKED :
|
||||||
|
case GIF_REGLIST :
|
||||||
|
ok_p = count == nloop * gif_nregs ();
|
||||||
|
break;
|
||||||
|
case GIF_IMAGE :
|
||||||
|
ok_p = count == nloop;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! ok_p)
|
||||||
|
{
|
||||||
|
as_bad ("nloop value does not match size of data");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DVP_INSN insn = bfd_getl32 (gif_insn_frag + 12);
|
||||||
|
char *file;
|
||||||
|
unsigned int line;
|
||||||
|
as_where (&file, &line);
|
||||||
|
insert_operand_final (DVP_GIF, &gif_operands[gif_operand_nloop],
|
||||||
|
DVP_MOD_THIS_WORD, &insn,
|
||||||
|
(offsetT) nloop, file, line);
|
||||||
|
bfd_putl32 ((bfd_vma) insn, gif_insn_frag + 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
gif_data_name = NULL;
|
||||||
|
demand_empty_rest_of_line ();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
s_endmpg (ignore)
|
s_endmpg (ignore)
|
||||||
int ignore;
|
int ignore;
|
||||||
|
Reference in New Issue
Block a user