* config/tc-v850.c (reg_name_search): Generalize to search
any given register table. (register_name): Pass appropriate table and size to reg_name_search. (system_register_name): New function. (SYSREG_NAME_CNT): Define. (md_assemble): Handle operands which are system registers. Still working on the parser..
This commit is contained in:
parent
e41c99bd11
commit
0e8f9bd15e
3 changed files with 93 additions and 18 deletions
|
@ -1,6 +1,13 @@
|
|||
start-sanitize-v850
|
||||
Fri Aug 23 10:41:32 1996 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* config/tc-v850.c (reg_name_search): Generalize to search
|
||||
any given register table.
|
||||
(register_name): Pass appropriate table and size to reg_name_search.
|
||||
(system_register_name): New function.
|
||||
(SYSREG_NAME_CNT): Define.
|
||||
(md_assemble): Handle operands which are system registers.
|
||||
|
||||
* config/tc-v850.c (md_assemble): If we find a register, but the
|
||||
opcode doesn't want a register, then we don't have a match.
|
||||
(md_assemble): Get size of the instruction from the opcode table.
|
||||
|
|
|
@ -25,6 +25,13 @@
|
|||
#include "subsegs.h"
|
||||
#include "opcode/v850.h"
|
||||
|
||||
/* Structure to hold information about predefined registers. */
|
||||
struct reg_name
|
||||
{
|
||||
const char *name;
|
||||
int value;
|
||||
};
|
||||
|
||||
/* Generic assembler global variables which must be defined by all targets. */
|
||||
|
||||
/* Characters which always start a comment. */
|
||||
|
@ -49,8 +56,9 @@ const char FLT_CHARS[] = "dD";
|
|||
static unsigned long v850_insert_operand
|
||||
PARAMS ((unsigned long insn, const struct v850_operand *operand,
|
||||
offsetT val, char *file, unsigned int line));
|
||||
static int reg_name_search PARAMS ((char *name));
|
||||
static int reg_name_search PARAMS ((char *name, const struct reg_name *, int));
|
||||
static boolean register_name PARAMS ((expressionS *expressionP));
|
||||
static boolean system_register_name PARAMS ((expressionS *expressionP));
|
||||
static int postfix PARAMS ((char *p));
|
||||
static bfd_reloc_code_real_type get_reloc PARAMS ((struct v850_operand *op));
|
||||
static unsigned long build_insn PARAMS ((struct v850_opcode *opcode, expressionS *opers));
|
||||
|
@ -91,13 +99,6 @@ const pseudo_typeS md_pseudo_table[] =
|
|||
/* Opcode hash table. */
|
||||
static struct hash_control *v850_hash;
|
||||
|
||||
/* Structure to hold information about predefined registers. */
|
||||
struct reg_name
|
||||
{
|
||||
const char *name;
|
||||
int value;
|
||||
};
|
||||
|
||||
/* This table is sorted. Suitable for searching by a binary search. */
|
||||
static const struct reg_name pre_defined_registers[] =
|
||||
{
|
||||
|
@ -152,6 +153,7 @@ static const struct reg_name system_registers[] =
|
|||
{ "ecr", 4 },
|
||||
{ "psw", 5 },
|
||||
};
|
||||
#define SYSREG_NAME_CNT (sizeof(system_registers) / sizeof(struct reg_name))
|
||||
|
||||
static const struct reg_name cc_names[] =
|
||||
{
|
||||
|
@ -177,30 +179,30 @@ static const struct reg_name cc_names[] =
|
|||
{ "z", 0x2 },
|
||||
};
|
||||
|
||||
/* reg_name_search does a binary search of the pre_defined_registers
|
||||
array to see if "name" is a valid regiter name. Returns the register
|
||||
/* reg_name_search does a binary search of the given register table
|
||||
to see if "name" is a valid regiter name. Returns the register
|
||||
number from the array on success, or -1 on failure. */
|
||||
|
||||
static int
|
||||
reg_name_search (name)
|
||||
reg_name_search (name, table, high)
|
||||
char *name;
|
||||
const struct reg_name *table;
|
||||
int high;
|
||||
{
|
||||
int middle, low, high;
|
||||
int middle, low;
|
||||
int cmp;
|
||||
|
||||
low = 0;
|
||||
high = REG_NAME_CNT - 1;
|
||||
|
||||
do
|
||||
{
|
||||
middle = (low + high) / 2;
|
||||
cmp = strcasecmp (name, pre_defined_registers[middle].name);
|
||||
cmp = strcasecmp (name, table[middle].name);
|
||||
if (cmp < 0)
|
||||
high = middle - 1;
|
||||
else if (cmp > 0)
|
||||
low = middle + 1;
|
||||
else
|
||||
return pre_defined_registers[middle].value;
|
||||
return table[middle].value;
|
||||
}
|
||||
while (low <= high);
|
||||
return -1;
|
||||
|
@ -230,7 +232,53 @@ register_name (expressionP)
|
|||
start = name = input_line_pointer;
|
||||
|
||||
c = get_symbol_end ();
|
||||
reg_number = reg_name_search (name);
|
||||
reg_number = reg_name_search (name, pre_defined_registers, REG_NAME_CNT - 1);
|
||||
|
||||
/* look to see if it's in the register table */
|
||||
if (reg_number >= 0)
|
||||
{
|
||||
expressionP->X_op = O_register;
|
||||
expressionP->X_add_number = reg_number;
|
||||
|
||||
/* make the rest nice */
|
||||
expressionP->X_add_symbol = NULL;
|
||||
expressionP->X_op_symbol = NULL;
|
||||
*input_line_pointer = c; /* put back the delimiting char */
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* reset the line as if we had not done anything */
|
||||
*input_line_pointer = c; /* put back the delimiting char */
|
||||
input_line_pointer = start; /* reset input_line pointer */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Summary of system_register_name().
|
||||
*
|
||||
* in: Input_line_pointer points to 1st char of operand.
|
||||
*
|
||||
* out: A expressionS.
|
||||
* The operand may have been a register: in this case, X_op == O_register,
|
||||
* X_add_number is set to the register number, and truth is returned.
|
||||
* Input_line_pointer->(next non-blank) char after operand, or is in
|
||||
* its original state.
|
||||
*/
|
||||
static boolean
|
||||
system_register_name (expressionP)
|
||||
expressionS *expressionP;
|
||||
{
|
||||
int reg_number;
|
||||
char *name;
|
||||
char *start;
|
||||
char c;
|
||||
|
||||
/* Find the spelling of the operand */
|
||||
start = name = input_line_pointer;
|
||||
|
||||
c = get_symbol_end ();
|
||||
reg_number = reg_name_search (name, system_registers, SYSREG_NAME_CNT - 1);
|
||||
|
||||
/* look to see if it's in the register table */
|
||||
if (reg_number >= 0)
|
||||
|
@ -452,6 +500,14 @@ md_assemble (str)
|
|||
goto error;
|
||||
}
|
||||
}
|
||||
else if ((operand->flags & V850_OPERAND_SRG) != 0)
|
||||
{
|
||||
if (!system_register_name(&ex))
|
||||
{
|
||||
errmsg = "invalid system register name";
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (strncmp(input_line_pointer, "lo(", 3) == 0)
|
||||
{
|
||||
input_line_pointer += 3;
|
||||
|
@ -506,6 +562,12 @@ md_assemble (str)
|
|||
errmsg = "syntax error: register not expected";
|
||||
goto error;
|
||||
}
|
||||
else if (system_register_name (&ex)
|
||||
&& (operand->flags & V850_OPERAND_SRG) == 0)
|
||||
{
|
||||
errmsg = "syntax error: system register not expected";
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
expression(&ex);
|
||||
|
@ -523,7 +585,7 @@ md_assemble (str)
|
|||
errmsg = "missing operand";
|
||||
goto error;
|
||||
case O_register:
|
||||
if ((operand->flags & V850_OPERAND_REG) == 0)
|
||||
if ((operand->flags & (V850_OPERAND_REG | V850_OPERAND_SRG)) == 0)
|
||||
{
|
||||
errmsg = "invalid operand";
|
||||
goto error;
|
||||
|
|
|
@ -23,6 +23,12 @@ else
|
|||
lose_these_too="arc ${lose_these_too}"
|
||||
fi
|
||||
|
||||
if ( echo $* | grep keep\-v850 > /dev/null ) ; then
|
||||
keep_these_too="v850 ${keep_these_too}"
|
||||
else
|
||||
lose_these_too="v850 ${lose_these_too}"
|
||||
fi
|
||||
|
||||
# All files listed between the "Things-to-keep:" line and the
|
||||
# "Files-to-sed:" line will be kept. All other files will be removed.
|
||||
# Directories listed in this section will have their own Sanitize
|
||||
|
|
Loading…
Add table
Reference in a new issue