=================================================================== Index: gas/config/tc-arm.c --- gas/config/tc-arm.c (revision 47) +++ gas/config/tc-arm.c (revision 48) @@ -707,12 +707,35 @@ static int in_my_get_expression = 0; +/* Third argument to my_get_expression. */ +#define GE_NO_PREFIX 0 +#define GE_IMM_PREFIX 1 +#define GE_OPT_PREFIX 2 + static int -my_get_expression (expressionS * ep, char ** str) +my_get_expression (expressionS * ep, char ** str, int prefix_mode) { char * save_in; segT seg; + switch (prefix_mode) + { + case GE_NO_PREFIX: break; + case GE_IMM_PREFIX: + if (!is_immediate_prefix (**str)) + { + inst.error = _("immediate expression requires a # prefix"); + return FAIL; + } + (*str)++; + break; + case GE_OPT_PREFIX: + if (is_immediate_prefix (**str)) + (*str)++; + break; + default: abort (); + } + memset (ep, 0, sizeof (expressionS)); save_in = input_line_pointer; @@ -765,9 +788,9 @@ return 0; } -#define expression_or_fail(exp, str) \ +#define expression_or_fail(exp, str, pmode) \ do { \ - if (my_get_expression (exp, str)) \ + if (my_get_expression (exp, str, pmode)) \ return; \ } while (0) @@ -972,16 +995,7 @@ bfd_boolean prefix_opt) { expressionS exp; - - if (is_immediate_prefix (**str)) - (*str)++; - else if (!prefix_opt) - { - inst.error = _("immediate expression requires a # prefix"); - return FAIL; - } - - my_get_expression (&exp, str); + my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX); if (exp.X_op != O_constant) { inst.error = _("constant expression required"); @@ -1332,7 +1346,7 @@ { expressionS expr; - if (my_get_expression (&expr, &str)) + if (my_get_expression (&expr, &str, GE_NO_PREFIX)) return FAIL; if (expr.X_op == O_constant) @@ -1505,25 +1519,22 @@ /* KIND indicates what kind of shifts are accepted. */ static int -decode_shift (char ** str, int kind) +decode_shift (char **str, int kind) { - const struct asm_shift_name * shift; - char * p; - char c; + const struct asm_shift_name *shift; + int reg; + char *p; - for (p = * str; ISALPHA (* p); p ++) + for (p = *str; ISALPHA (*p); p++) ; - if (p == * str) + if (p == *str) { inst.error = _("shift expression expected"); return FAIL; } - c = * p; - * p = '\0'; - shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str); - * p = c; + shift = hash_find_n (arm_shift_hsh, *str, p - *str); if (shift == NULL) { @@ -1531,7 +1542,8 @@ return FAIL; } - assert (shift->properties->index == shift_properties[shift->properties->index].index); + assert (shift->properties->index == + shift_properties[shift->properties->index].index); if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE && shift->properties->index != SHIFT_LSL @@ -1555,7 +1567,7 @@ if (shift->properties->index == SHIFT_RRX) { - * str = p; + *str = p; inst.instruction |= shift->properties->bit_field; return SUCCESS; } @@ -1563,25 +1575,14 @@ skip_whitespace (p); if (kind == NO_SHIFT_RESTRICT - && reg_required_here (& p, 8, REG_TYPE_RN) != FAIL) + && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL) { inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG; - * str = p; + inst.instruction |= reg << 8; + *str = p; return SUCCESS; } - else if (! is_immediate_prefix (* p)) - { - inst.error = (NO_SHIFT_RESTRICT - ? _("shift requires register or #expression") - : _("shift requires #expression")); - * str = p; - return FAIL; - } - - inst.error = NULL; - p ++; - - if (my_get_expression (& inst.reloc.exp, & p)) + else if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX)) return FAIL; /* Validate some simple #expressions. */ @@ -1726,85 +1727,72 @@ int value; expressionS expr; - if (reg_required_here (str, 0, REG_TYPE_RN) != FAIL) + if ((value = arm_reg_parse (str, REG_TYPE_RN)) != FAIL) { + inst.instruction |= value; if (skip_past_comma (str) == SUCCESS) /* Shift operation on register. */ return decode_shift (str, NO_SHIFT_RESTRICT); return SUCCESS; } + else if (my_get_expression (&inst.reloc.exp, str, GE_IMM_PREFIX)) + return FAIL; + + if (inst.reloc.exp.X_add_symbol) + { + inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE; + inst.reloc.pc_rel = 0; + } else { - /* Immediate expression. */ - if (is_immediate_prefix (**str)) + if (skip_past_comma (str) == SUCCESS) { - (*str)++; - inst.error = NULL; - - if (my_get_expression (&inst.reloc.exp, str)) + /* #x, y -- ie explicit rotation by Y. */ + if (my_get_expression (&expr, str, GE_NO_PREFIX)) return FAIL; - if (inst.reloc.exp.X_add_symbol) + if (expr.X_op != O_constant) { - inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE; - inst.reloc.pc_rel = 0; + inst.error = _("constant expression expected"); + return FAIL; } - else - { - if (skip_past_comma (str) == SUCCESS) - { - /* #x, y -- ie explicit rotation by Y. */ - if (my_get_expression (&expr, str)) - return FAIL; - if (expr.X_op != O_constant) - { - inst.error = _("constant expression expected"); - return FAIL; - } - - /* Rotate must be a multiple of 2. */ - if (((unsigned) expr.X_add_number) > 30 - || (expr.X_add_number & 1) != 0 - || ((unsigned) inst.reloc.exp.X_add_number) > 255) - { - inst.error = _("invalid constant"); - return FAIL; - } - inst.instruction |= INST_IMMEDIATE; - inst.instruction |= inst.reloc.exp.X_add_number; - inst.instruction |= expr.X_add_number << 7; - return SUCCESS; - } - - /* Implicit rotation, select a suitable one. */ - value = validate_immediate (inst.reloc.exp.X_add_number); - - if (value == FAIL) - { - /* Can't be done. Perhaps the code reads something like - "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */ - if ((value = negate_data_op (&inst.instruction, - inst.reloc.exp.X_add_number)) - == FAIL) - { - inst.error = _("invalid constant"); - return FAIL; - } - } - - inst.instruction |= value; + /* Rotate must be a multiple of 2. */ + if (((unsigned) expr.X_add_number) > 30 + || (expr.X_add_number & 1) != 0 + || ((unsigned) inst.reloc.exp.X_add_number) > 255) + { + inst.error = _("invalid constant"); + return FAIL; } - inst.instruction |= INST_IMMEDIATE; + inst.instruction |= inst.reloc.exp.X_add_number; + inst.instruction |= expr.X_add_number << 7; return SUCCESS; } - (*str)++; - inst.error = _("register or shift expression expected"); - return FAIL; + /* Implicit rotation, select a suitable one. */ + value = validate_immediate (inst.reloc.exp.X_add_number); + + if (value == FAIL) + { + /* Can't be done. Perhaps the code reads something like + "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */ + if ((value = negate_data_op (&inst.instruction, + inst.reloc.exp.X_add_number)) + == FAIL) + { + inst.error = _("invalid constant"); + return FAIL; + } + } + + inst.instruction |= value; } + + inst.instruction |= INST_IMMEDIATE; + return SUCCESS; } /* Parse an explicit relocation suffix on an expression. This is @@ -1846,7 +1834,7 @@ case '#': case '$': (*str)++; - if (my_get_expression (& inst.reloc.exp, str)) + if (my_get_expression (& inst.reloc.exp, str, GE_NO_PREFIX)) return FAIL; if (inst.reloc.exp.X_op == O_constant) @@ -1904,7 +1892,7 @@ case '#': case '$': (*str)++; - if (my_get_expression (& inst.reloc.exp, str)) + if (my_get_expression (& inst.reloc.exp, str, GE_NO_PREFIX)) return FAIL; if (inst.reloc.exp.X_op == O_constant) @@ -2028,7 +2016,7 @@ return FAIL; else /* PC +- 8 bit immediate offset. */ { - if (my_get_expression (& inst.reloc.exp, & str)) + if (my_get_expression (& inst.reloc.exp, & str, GE_NO_PREFIX)) return FAIL; inst.instruction |= HWOFFSET_IMM; /* The I bit. */ @@ -2109,23 +2097,6 @@ } static int -cp_address_offset (char ** str, int reloc) -{ - if (! is_immediate_prefix (**str)) - { - inst.error = _("immediate expression expected"); - return FAIL; - } - (*str)++; - if (my_get_expression (& inst.reloc.exp, str)) - return FAIL; - - inst.reloc.type = reloc; - - return SUCCESS; -} - -static int cp_address_required_here (char ** str, int wb_ok, int reloc) { char * p = * str; @@ -2175,8 +2146,9 @@ return FAIL; } - if (cp_address_offset (&p, reloc) == FAIL) + if (my_get_expression (& inst.reloc.exp, &p, GE_IMM_PREFIX)) return FAIL; + inst.reloc.type = reloc; } else pre_inc = PRE_INDEX | INDEX_UP; @@ -2218,11 +2190,11 @@ return FAIL; } + if (my_get_expression (& inst.reloc.exp, &p, GE_IMM_PREFIX)) + return FAIL; + inst.reloc.type = reloc; pre_inc = PRE_INDEX; - if (cp_address_offset (&p, reloc) == FAIL) - return FAIL; - if (*p++ != ']') { inst.error = _("missing ]"); @@ -2244,7 +2216,7 @@ } else { - if (my_get_expression (&inst.reloc.exp, &p)) + if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX)) return FAIL; inst.reloc.type = reloc; @@ -2291,16 +2263,8 @@ inst.operands[i].isreg = 1; if (skip_past_comma (&s) != FAIL) { - if (is_immediate_prefix (*s)) + if ((Ro = arm_reg_parse (&s, REG_TYPE_RN)) != FAIL) { - s++; - if (my_get_expression (&inst.reloc.exp, &s)) - return FAIL; - } - else - { - if ((Ro = arm_reg_parse (&s, REG_TYPE_RN)) == FAIL) - return FAIL; if (Ro > 7 || Rb > 7) { inst.error = BAD_HIREG; @@ -2309,6 +2273,8 @@ inst.operands[i].imm = Ro; inst.operands[i].immisreg = 1; } + else if (my_get_expression (&inst.reloc.exp, &s, GE_IMM_PREFIX)) + return FAIL; } else { @@ -2325,7 +2291,7 @@ else if (*s == '=') { s++; - if (my_get_expression (&inst.reloc.exp, &s)) + if (my_get_expression (&inst.reloc.exp, &s, GE_NO_PREFIX)) return FAIL; if ( inst.reloc.exp.X_op != O_constant @@ -2337,7 +2303,7 @@ } else { - if (my_get_expression (&inst.reloc.exp, &s)) + if (my_get_expression (&inst.reloc.exp, &s, GE_NO_PREFIX)) return FAIL; inst.reloc.exp.X_add_number -= 4; /* Pipeline offset. */ @@ -4363,19 +4329,19 @@ /* Expressions */ case OP_(iEXP): iEXP: - if (is_immediate_prefix (*str)) - str++; - /* fall through */ + if (my_get_expression (&inst.reloc.exp, &str, GE_OPT_PREFIX)) + return FAIL; + break; case OP_(EXP): EXP: - if (my_get_expression (&inst.reloc.exp, &str)) + if (my_get_expression (&inst.reloc.exp, &str, GE_NO_PREFIX)) return FAIL; break; case OP_(EXPr): EXPr: - if (my_get_expression (&inst.reloc.exp, &str)) + if (my_get_expression (&inst.reloc.exp, &str, GE_NO_PREFIX)) return FAIL; if (inst.reloc.exp.X_op == O_symbol) { @@ -5124,7 +5090,7 @@ /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */ str++; - expression_or_fail (&inst.reloc.exp, &str); + expression_or_fail (&inst.reloc.exp, &str, GE_NO_PREFIX); if (inst.reloc.exp.X_op != O_constant && inst.reloc.exp.X_op != O_symbol) @@ -5178,7 +5144,7 @@ } else { - expression_or_fail (&inst.reloc.exp, &str); + expression_or_fail (&inst.reloc.exp, &str, GE_NO_PREFIX); inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM; #ifndef TE_WINCE @@ -5351,7 +5317,7 @@ /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */ str++; - expression_or_fail (&inst.reloc.exp, &str); + expression_or_fail (&inst.reloc.exp, &str, GE_NO_PREFIX); if (inst.reloc.exp.X_op != O_constant && inst.reloc.exp.X_op != O_symbol) @@ -5404,7 +5370,7 @@ } else { - expression_or_fail (&inst.reloc.exp, &str); + expression_or_fail (&inst.reloc.exp, &str, GE_NO_PREFIX); inst.instruction |= HWOFFSET_IMM; inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;