Support constant expressions as register lists.

This commit is contained in:
Nick Clifton
1997-08-25 18:21:02 +00:00
parent 591ebe4255
commit cf735d2a93
2 changed files with 111 additions and 21 deletions

View File

@ -1,4 +1,14 @@
start-sanitize-v850 start-sanitize-v850
Mon Aug 25 11:21:48 1997 Nick Clifton <nickc@cygnus.com>
* config/tc-v850.c (md_assemble): Restore input_line_pointer upon
exit.
start-sanitize-v850e
* config/tc-v850.c (parse_register_list): Support constant
expressions as register lists.
start-sanitize-v850e
Mon Aug 25 10:19:34 1997 Nick Clifton <nickc@cygnus.com> Mon Aug 25 10:19:34 1997 Nick Clifton <nickc@cygnus.com>
* doc/c-v850.texi: Change the major node to v850 Machine * doc/c-v850.texi: Change the major node to v850 Machine

View File

@ -439,8 +439,23 @@ skip_white_space (void)
* out: True if the parse completed successfully, False otherwise. * out: True if the parse completed successfully, False otherwise.
* If the parse completes the correct bit fields in the * If the parse completes the correct bit fields in the
* instruction will be filled in. * instruction will be filled in.
*
* Parses register lists with the syntax:
*
* { rX }
* { rX, rY }
* { rX - rY }
* { rX - rY, rZ }
* etc
*
* and also parses constant epxressions whoes bits indicate the
* registers in the lists. The LSB in the expression refers to
* the lowest numbered permissable register in the register list,
* and so on upwards. System registers are considered to be very
* high numbers.
*
*/ */
static boolean static char *
parse_register_list parse_register_list
( (
unsigned long * insn, unsigned long * insn,
@ -453,6 +468,8 @@ parse_register_list
static int type3_regs[ 32 ] = { 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 15, 13, 12, 7, 6, 5, 4, 11, 10, 9, 8 }; static int type3_regs[ 32 ] = { 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 15, 13, 12, 7, 6, 5, 4, 11, 10, 9, 8 };
/* end-sanitize-v850eq */ /* end-sanitize-v850eq */
int * regs; int * regs;
expressionS exp;
/* Select a register array to parse. */ /* Select a register array to parse. */
switch (operand->shift) switch (operand->shift)
@ -464,15 +481,80 @@ parse_register_list
/* end-sanitize-v850eq */ /* end-sanitize-v850eq */
default: default:
as_bad ("unknown operand shift: %x\n", operand->shift ); as_bad ("unknown operand shift: %x\n", operand->shift );
return false; return "internal failure in parse_register_list";
} }
skip_white_space(); skip_white_space();
/* If the expression starts with a curly brace it is a register list.
Otherwise it is a constant expression ,whoes bits indicate which
registers are to be included in the list. */
if (* input_line_pointer != '{') if (* input_line_pointer != '{')
{ {
as_bad ("no opening curly brace at start of register list\n"); int bits;
return false; int reg;
int i;
expression (& exp);
if (exp.X_op != O_constant)
return "constant expression or register list expected";
/* start-sanitize-v850eq */
if (regs == type1_regs)
/* end-sanitize-v850eq */
{
if (exp.X_add_number & 0xFFFFF000)
return "high bits set in register list expression";
for (reg = 20; reg < 32; reg ++)
if (exp.X_add_number & (1 << (reg - 20)))
{
for (i = 0; i < 32; i++)
if (regs[i] == reg)
* insn |= (1 << i);
}
}
/* start-sanitize-v850eq */
else if (regs == type2_regs)
{
if (exp.X_add_number & 0xFFFE0000)
return "high bits set in register list expression";
for (reg = 1; reg < 16; reg ++)
if (exp.X_add_number & (1 << (reg - 1)))
{
for (i = 0; i < 32; i++)
if (regs[i] == reg)
* insn |= (1 << i);
}
if (exp.X_add_number & (1 << 15))
* insn |= (1 << 3);
if (exp.X_add_number & (1 << 16))
* insn |= (1 << 19);
}
else /* regs == type3_regs */
{
if (exp.X_add_number & 0xFFFE0000)
return "high bits set in register list expression";
for (reg = 16; reg < 32; reg ++)
if (exp.X_add_number & (1 << (reg - 16)))
{
for (i = 0; i < 32; i++)
if (regs[i] == reg)
* insn |= (1 << i);
}
if (exp.X_add_number & (1 << 16))
* insn |= (1 << 19);
}
/* end-sanitize-v850eq */
return NULL;
} }
input_line_pointer ++; input_line_pointer ++;
@ -480,8 +562,6 @@ parse_register_list
/* Parse the register list until a terminator (closing curly brace or new-line) is found. */ /* Parse the register list until a terminator (closing curly brace or new-line) is found. */
for (;;) for (;;)
{ {
expressionS exp;
if (register_name (& exp)) if (register_name (& exp))
{ {
int i; int i;
@ -498,21 +578,19 @@ parse_register_list
if (i == 32) if (i == 32)
{ {
as_bad( "it is illegal to include register r%d in list\n", exp.X_add_number ); return "illegal register included in list";
return false;
} }
} }
else if (system_register_name (& exp, true)) else if (system_register_name (& exp, true))
{ {
if (regs == type1_regs) if (regs == type1_regs)
{ {
as_bad ("system registers cannot be included in this register list" ); return "system registers cannot be included in list";
return false;
} }
else if (exp.X_add_number == 5) else if (exp.X_add_number == 5)
{ {
if (regs == type2_regs) if (regs == type2_regs)
as_bad ("PSW cannot be included in this register list" ); return "PSW cannot be included in list";
else else
* insn |= 0x8; * insn |= 0x8;
} }
@ -541,7 +619,7 @@ parse_register_list
/* Get the second register in the range. */ /* Get the second register in the range. */
if (! register_name (& exp2)) if (! register_name (& exp2))
{ {
as_bad ("second register should follow dash in register list\n"); return "second register should follow dash in register list";
exp2.X_add_number = exp.X_add_number; exp2.X_add_number = exp.X_add_number;
} }
@ -562,8 +640,7 @@ parse_register_list
if (i == 32) if (i == 32)
{ {
as_bad( "it is illegal to include register r%d in list\n", j ); return "illegal register included in list";
return false;
} }
} }
} }
@ -575,7 +652,7 @@ parse_register_list
skip_white_space(); skip_white_space();
} }
return true; return NULL;
} }
/* end-sanitize-v850e */ /* end-sanitize-v850e */
@ -820,6 +897,7 @@ md_assemble (str)
boolean extra_data_after_insn = false; boolean extra_data_after_insn = false;
unsigned extra_data_len; unsigned extra_data_len;
unsigned long extra_data; unsigned long extra_data;
char * saved_input_line_pointer;
/* Get the opcode. */ /* Get the opcode. */
@ -839,11 +917,13 @@ md_assemble (str)
} }
str = s; str = s;
while (isspace (*str)) while (isspace (* str))
++str; ++ str;
start_of_operands = str; start_of_operands = str;
saved_input_line_pointer = input_line_pointer;
for (;;) for (;;)
{ {
const char * errmsg = NULL; const char * errmsg = NULL;
@ -998,10 +1078,7 @@ md_assemble (str)
} }
else if (operand->flags & V850E_PUSH_POP) else if (operand->flags & V850E_PUSH_POP)
{ {
if (! parse_register_list (& insn, operand)) errmsg = parse_register_list (& insn, operand);
{
errmsg = "invalid register list";
}
/* The parse_register_list() function has already done everything, so fake a dummy expression. */ /* The parse_register_list() function has already done everything, so fake a dummy expression. */
ex.X_op = O_constant; ex.X_op = O_constant;
@ -1133,6 +1210,7 @@ md_assemble (str)
as_bad ("%s", errmsg); as_bad ("%s", errmsg);
ignore_rest_of_line (); ignore_rest_of_line ();
input_line_pointer = saved_input_line_pointer;
return; return;
} }
break; break;
@ -1241,6 +1319,8 @@ md_assemble (str)
(fixups[i].opindex + (int) BFD_RELOC_UNUSED))); (fixups[i].opindex + (int) BFD_RELOC_UNUSED)));
} }
} }
input_line_pointer = saved_input_line_pointer;
} }