mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-22 02:50:08 +08:00
Thu Jul 25 15:22:51 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
* tc-d10v.c (md_assemble): Now handles multiline instructions.
This commit is contained in:
@ -55,6 +55,7 @@ static Fixups *fixups;
|
||||
/* local functions */
|
||||
static int reg_name_search PARAMS ((char *name));
|
||||
static int register_name PARAMS ((expressionS *expressionP));
|
||||
static int check_range PARAMS ((unsigned long num, int bits, int sign));
|
||||
static int postfix PARAMS ((char *p));
|
||||
static bfd_reloc_code_real_type get_reloc PARAMS ((struct d10v_operand *op));
|
||||
static int get_operands PARAMS ((expressionS exp[]));
|
||||
@ -400,8 +401,6 @@ d10v_insert_operand (insn, op_type, value, left)
|
||||
bits = d10v_operands[op_type].bits;
|
||||
|
||||
/* truncate to the proper number of bits */
|
||||
/* FIXME: overflow checking here? */
|
||||
|
||||
if (check_range (value, bits, d10v_operands[op_type].flags & OPERAND_SIGNED))
|
||||
as_bad("operand out of range: %d",value);
|
||||
|
||||
@ -663,51 +662,70 @@ md_assemble (str)
|
||||
{
|
||||
struct d10v_opcode *opcode;
|
||||
unsigned long insn;
|
||||
int t=0;
|
||||
int extype=0; /* execution type; parallel, etc */
|
||||
static int etype=0; /* saved extype. used for multiline instructions */
|
||||
char *str2;
|
||||
|
||||
/* printf("md_assemble: str=%s\n",str); */
|
||||
|
||||
/* look for the special multiple instruction seperators */
|
||||
str2 = strstr (str, "||");
|
||||
if (str2)
|
||||
t = 1;
|
||||
else
|
||||
if (etype == 0)
|
||||
{
|
||||
str2 = strstr (str, "->");
|
||||
/* look for the special multiple instruction separators */
|
||||
str2 = strstr (str, "||");
|
||||
if (str2)
|
||||
t = 2;
|
||||
extype = 1;
|
||||
else
|
||||
{
|
||||
str2 = strstr (str, "<-");
|
||||
str2 = strstr (str, "->");
|
||||
if (str2)
|
||||
t = 3;
|
||||
extype = 2;
|
||||
else
|
||||
{
|
||||
str2 = strstr (str, "<-");
|
||||
if (str2)
|
||||
extype = 3;
|
||||
}
|
||||
}
|
||||
/* str2 points to the separator, if one */
|
||||
if (str2)
|
||||
{
|
||||
*str2 = 0;
|
||||
|
||||
/* if two instructions are present and we already have one saved
|
||||
then first write it out */
|
||||
if (prev_opcode)
|
||||
write_1_short (prev_opcode, prev_insn, fixups->next);
|
||||
|
||||
/* assemble first instruction and save it */
|
||||
prev_insn = do_assemble (str, &prev_opcode);
|
||||
if (prev_insn == -1)
|
||||
as_fatal ("can't find opcode ");
|
||||
fixups = fixups->next;
|
||||
str = str2 + 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* str2 points to the seperator, if one */
|
||||
if (str2)
|
||||
insn = do_assemble (str, &opcode);
|
||||
if (insn == -1)
|
||||
{
|
||||
*str2 = 0;
|
||||
|
||||
/* if two instructions are present and we already have one saved
|
||||
then first write it out */
|
||||
if (prev_opcode)
|
||||
write_1_short (prev_opcode, prev_insn, fixups->next);
|
||||
|
||||
/* assemble first instruction and save it */
|
||||
prev_insn = do_assemble (str, &prev_opcode);
|
||||
fixups = fixups->next;
|
||||
str = str2 + 2;
|
||||
if (extype)
|
||||
{
|
||||
etype = extype;
|
||||
return;
|
||||
}
|
||||
as_fatal ("can't find opcode ");
|
||||
}
|
||||
|
||||
insn = do_assemble (str, &opcode);
|
||||
if (etype)
|
||||
{
|
||||
extype = etype;
|
||||
etype = 0;
|
||||
}
|
||||
|
||||
/* if this is a long instruction, write it and any previous short instruction */
|
||||
if (opcode->format & LONG_OPCODE)
|
||||
{
|
||||
if (t)
|
||||
if (extype)
|
||||
as_fatal("Unable to mix instructions as specified");
|
||||
if (prev_opcode)
|
||||
{
|
||||
@ -719,14 +737,14 @@ md_assemble (str)
|
||||
return;
|
||||
}
|
||||
|
||||
if (prev_opcode && (write_2_short (prev_opcode, prev_insn, opcode, insn, t, fixups) == 0))
|
||||
if (prev_opcode && (write_2_short (prev_opcode, prev_insn, opcode, insn, extype, fixups) == 0))
|
||||
{
|
||||
/* no instructions saved */
|
||||
prev_opcode = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t)
|
||||
if (extype)
|
||||
as_fatal("Unable to mix instructions as specified");
|
||||
/* save off last instruction so it may be packed on next pass */
|
||||
prev_opcode = opcode;
|
||||
@ -738,6 +756,9 @@ md_assemble (str)
|
||||
}
|
||||
|
||||
|
||||
/* do_assemble assembles a single instruction and returns an opcode */
|
||||
/* it returns -1 (an invalid opcode) on error */
|
||||
|
||||
static unsigned long
|
||||
do_assemble (str, opcode)
|
||||
char *str;
|
||||
@ -770,15 +791,12 @@ do_assemble (str, opcode)
|
||||
name[nlen] = 0;
|
||||
|
||||
if (nlen == 0)
|
||||
as_bad ("can't find opcode ");
|
||||
return (-1);
|
||||
|
||||
/* find the first opcode with the proper name */
|
||||
*opcode = (struct d10v_opcode *)hash_find (d10v_hash, name);
|
||||
if (*opcode == NULL)
|
||||
{
|
||||
as_fatal ("unknown opcode: %s",name);
|
||||
return;
|
||||
}
|
||||
|
||||
save = input_line_pointer;
|
||||
input_line_pointer = op_end;
|
||||
@ -821,7 +839,7 @@ do_assemble (str, opcode)
|
||||
else
|
||||
{
|
||||
/* now search the opcode table table for one with operands */
|
||||
/* that match what we've got */
|
||||
/* that matches what we've got */
|
||||
while (!match)
|
||||
{
|
||||
match = 1;
|
||||
|
Reference in New Issue
Block a user