From 0e8f9bd15e1ddb8f2635c653572374ed5305ee5a Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Fri, 23 Aug 1996 17:39:43 +0000 Subject: * 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.. --- gas/ChangeLog | 7 ++++ gas/config/tc-v850.c | 98 ++++++++++++++++++++++++++++++++++++--------- gas/testsuite/gas/.Sanitize | 6 +++ 3 files changed, 93 insertions(+), 18 deletions(-) (limited to 'gas') diff --git a/gas/ChangeLog b/gas/ChangeLog index 151bf2f..be43f8f 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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. diff --git a/gas/config/tc-v850.c b/gas/config/tc-v850.c index adc17e7..e59011e 100644 --- a/gas/config/tc-v850.c +++ b/gas/config/tc-v850.c @@ -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; diff --git a/gas/testsuite/gas/.Sanitize b/gas/testsuite/gas/.Sanitize index c7957d1..76dc860 100644 --- a/gas/testsuite/gas/.Sanitize +++ b/gas/testsuite/gas/.Sanitize @@ -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 -- cgit v1.1