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:
Martin Hunt
1996-07-25 22:27:37 +00:00
parent 35ad20a1a5
commit ef5a4085ce

View File

@ -55,6 +55,7 @@ static Fixups *fixups;
/* local functions */ /* local functions */
static int reg_name_search PARAMS ((char *name)); static int reg_name_search PARAMS ((char *name));
static int register_name PARAMS ((expressionS *expressionP)); 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 int postfix PARAMS ((char *p));
static bfd_reloc_code_real_type get_reloc PARAMS ((struct d10v_operand *op)); static bfd_reloc_code_real_type get_reloc PARAMS ((struct d10v_operand *op));
static int get_operands PARAMS ((expressionS exp[])); 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; bits = d10v_operands[op_type].bits;
/* truncate to the proper number of bits */ /* truncate to the proper number of bits */
/* FIXME: overflow checking here? */
if (check_range (value, bits, d10v_operands[op_type].flags & OPERAND_SIGNED)) if (check_range (value, bits, d10v_operands[op_type].flags & OPERAND_SIGNED))
as_bad("operand out of range: %d",value); as_bad("operand out of range: %d",value);
@ -663,30 +662,31 @@ md_assemble (str)
{ {
struct d10v_opcode *opcode; struct d10v_opcode *opcode;
unsigned long insn; 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; char *str2;
/* printf("md_assemble: str=%s\n",str); */ /* printf("md_assemble: str=%s\n",str); */
/* look for the special multiple instruction seperators */ if (etype == 0)
{
/* look for the special multiple instruction separators */
str2 = strstr (str, "||"); str2 = strstr (str, "||");
if (str2) if (str2)
t = 1; extype = 1;
else else
{ {
str2 = strstr (str, "->"); str2 = strstr (str, "->");
if (str2) if (str2)
t = 2; extype = 2;
else else
{ {
str2 = strstr (str, "<-"); str2 = strstr (str, "<-");
if (str2) if (str2)
t = 3; extype = 3;
} }
} }
/* str2 points to the separator, if one */
/* str2 points to the seperator, if one */
if (str2) if (str2)
{ {
*str2 = 0; *str2 = 0;
@ -698,16 +698,34 @@ md_assemble (str)
/* assemble first instruction and save it */ /* assemble first instruction and save it */
prev_insn = do_assemble (str, &prev_opcode); prev_insn = do_assemble (str, &prev_opcode);
if (prev_insn == -1)
as_fatal ("can't find opcode ");
fixups = fixups->next; fixups = fixups->next;
str = str2 + 2; str = str2 + 2;
} }
}
insn = do_assemble (str, &opcode); insn = do_assemble (str, &opcode);
if (insn == -1)
{
if (extype)
{
etype = extype;
return;
}
as_fatal ("can't find opcode ");
}
if (etype)
{
extype = etype;
etype = 0;
}
/* if this is a long instruction, write it and any previous short instruction */ /* if this is a long instruction, write it and any previous short instruction */
if (opcode->format & LONG_OPCODE) if (opcode->format & LONG_OPCODE)
{ {
if (t) if (extype)
as_fatal("Unable to mix instructions as specified"); as_fatal("Unable to mix instructions as specified");
if (prev_opcode) if (prev_opcode)
{ {
@ -719,14 +737,14 @@ md_assemble (str)
return; 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 */ /* no instructions saved */
prev_opcode = NULL; prev_opcode = NULL;
} }
else else
{ {
if (t) if (extype)
as_fatal("Unable to mix instructions as specified"); as_fatal("Unable to mix instructions as specified");
/* save off last instruction so it may be packed on next pass */ /* save off last instruction so it may be packed on next pass */
prev_opcode = opcode; 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 static unsigned long
do_assemble (str, opcode) do_assemble (str, opcode)
char *str; char *str;
@ -770,15 +791,12 @@ do_assemble (str, opcode)
name[nlen] = 0; name[nlen] = 0;
if (nlen == 0) if (nlen == 0)
as_bad ("can't find opcode "); return (-1);
/* find the first opcode with the proper name */ /* find the first opcode with the proper name */
*opcode = (struct d10v_opcode *)hash_find (d10v_hash, name); *opcode = (struct d10v_opcode *)hash_find (d10v_hash, name);
if (*opcode == NULL) if (*opcode == NULL)
{
as_fatal ("unknown opcode: %s",name); as_fatal ("unknown opcode: %s",name);
return;
}
save = input_line_pointer; save = input_line_pointer;
input_line_pointer = op_end; input_line_pointer = op_end;
@ -821,7 +839,7 @@ do_assemble (str, opcode)
else else
{ {
/* now search the opcode table table for one with operands */ /* now search the opcode table table for one with operands */
/* that match what we've got */ /* that matches what we've got */
while (!match) while (!match)
{ {
match = 1; match = 1;