mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-07-30 21:34:42 +08:00
Support constant expressions as register lists.
This commit is contained in:
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user